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.cs139
1 files changed, 106 insertions, 33 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index c0a4e56..50dae2a 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -236,7 +236,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
236 /// <summary>Handlers for incoming packets</summary> 236 /// <summary>Handlers for incoming packets</summary>
237 //PacketEventDictionary packetEvents = new PacketEventDictionary(); 237 //PacketEventDictionary packetEvents = new PacketEventDictionary();
238 /// <summary>Incoming packets that are awaiting handling</summary> 238 /// <summary>Incoming packets that are awaiting handling</summary>
239 private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>(); 239 //private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>();
240
241 private DoubleQueue<IncomingPacket> packetInbox = new DoubleQueue<IncomingPacket>();
240 242
241 /// <summary></summary> 243 /// <summary></summary>
242 //private UDPClientCollection m_clients = new UDPClientCollection(); 244 //private UDPClientCollection m_clients = new UDPClientCollection();
@@ -291,6 +293,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
291 /// <summary>Flag to signal when clients should send pings</summary> 293 /// <summary>Flag to signal when clients should send pings</summary>
292 protected bool m_sendPing; 294 protected bool m_sendPing;
293 295
296 private ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>();
297
294 /// <summary> 298 /// <summary>
295 /// Event used to signal when queued packets are available for sending. 299 /// Event used to signal when queued packets are available for sending.
296 /// </summary> 300 /// </summary>
@@ -1058,6 +1062,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1058 1062
1059 #region Queue or Send 1063 #region Queue or Send
1060 1064
1065 bool highPriority = false;
1066
1067 if (category != ThrottleOutPacketType.Unknown && (category & ThrottleOutPacketType.HighPriority) != 0)
1068 {
1069 category = (ThrottleOutPacketType)((int)category & 127);
1070 highPriority = true;
1071 }
1072
1061 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null); 1073 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null);
1062 // If we were not provided a method for handling unacked, use the UDPServer default method 1074 // If we were not provided a method for handling unacked, use the UDPServer default method
1063 outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method); 1075 outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method);
@@ -1066,15 +1078,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1066 // continue to display the deleted object until relog. Therefore, we need to always queue a kill object 1078 // continue to display the deleted object until relog. Therefore, we need to always queue a kill object
1067 // packet so that it isn't sent before a queued update packet. 1079 // packet so that it isn't sent before a queued update packet.
1068 bool requestQueue = type == PacketType.KillObject; 1080 bool requestQueue = type == PacketType.KillObject;
1081 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue, highPriority))
1069 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue)) 1082 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue))
1070 { 1083 {
1071 SendPacketFinal(outgoingPacket); 1084 SendPacketFinal(outgoingPacket);
1072 return true; 1085 return true;
1073 } 1086 }
1074 else 1087
1075 { 1088 return false;
1076 return false;
1077 }
1078 1089
1079 #endregion Queue or Send 1090 #endregion Queue or Send
1080 } 1091 }
@@ -1372,34 +1383,59 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1372 1383
1373 #region Packet to Client Mapping 1384 #region Packet to Client Mapping
1374 1385
1375 // UseCircuitCode handling 1386 // If there is already a client for this endpoint, don't process UseCircuitCode
1376 if (packet.Type == PacketType.UseCircuitCode) 1387 IClientAPI client = null;
1388 if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
1377 { 1389 {
1378 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the 1390 // UseCircuitCode handling
1379 // buffer. 1391 if (packet.Type == PacketType.UseCircuitCode)
1380 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; 1392 {
1393 // And if there is a UseCircuitCode pending, also drop it
1394 lock (m_pendingCache)
1395 {
1396 if (m_pendingCache.Contains(endPoint))
1397 return;
1381 1398
1382 Util.FireAndForget(HandleUseCircuitCode, array); 1399 m_pendingCache.AddOrUpdate(endPoint, new Queue<UDPPacketBuffer>(), 60);
1400 }
1383 1401
1384 return; 1402 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the
1403 // buffer.
1404 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
1405
1406 Util.FireAndForget(HandleUseCircuitCode, array);
1407
1408 return;
1409 }
1385 } 1410 }
1386 else if (packet.Type == PacketType.CompleteAgentMovement) 1411
1412 // If this is a pending connection, enqueue, don't process yet
1413 lock (m_pendingCache)
1387 { 1414 {
1388 // Send ack straight away to let the viewer know that we got it. 1415 Queue<UDPPacketBuffer> queue;
1389 SendAckImmediate(endPoint, packet.Header.Sequence); 1416 if (m_pendingCache.TryGetValue(endPoint, out queue))
1417 {
1418 //m_log.DebugFormat("[LLUDPSERVER]: Enqueued a {0} packet into the pending queue", packet.Type);
1419 queue.Enqueue(buffer);
1420 return;
1421 }
1422 else if (packet.Type == PacketType.CompleteAgentMovement)
1423 {
1424 // Send ack straight away to let the viewer know that we got it.
1425 SendAckImmediate(endPoint, packet.Header.Sequence);
1390 1426
1391 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the 1427 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the
1392 // buffer. 1428 // buffer.
1393 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; 1429 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
1394 1430
1395 Util.FireAndForget(HandleCompleteMovementIntoRegion, array); 1431 Util.FireAndForget(HandleCompleteMovementIntoRegion, array);
1396 1432
1397 return; 1433 return;
1434 }
1398 } 1435 }
1399 1436
1400 // Determine which agent this packet came from 1437 // Determine which agent this packet came from
1401 IClientAPI client; 1438 if (client == null || !(client is LLClientView))
1402 if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
1403 { 1439 {
1404 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); 1440 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName);
1405 1441
@@ -1416,7 +1452,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1416 udpClient = ((LLClientView)client).UDPClient; 1452 udpClient = ((LLClientView)client).UDPClient;
1417 1453
1418 if (!udpClient.IsConnected) 1454 if (!udpClient.IsConnected)
1455 {
1456 m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet for a unConnected client in " + m_scene.RegionInfo.RegionName);
1419 return; 1457 return;
1458 }
1420 1459
1421 #endregion Packet to Client Mapping 1460 #endregion Packet to Client Mapping
1422 1461
@@ -1570,7 +1609,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1570 incomingPacket = new IncomingPacket((LLClientView)client, packet); 1609 incomingPacket = new IncomingPacket((LLClientView)client, packet);
1571 } 1610 }
1572 1611
1573 packetInbox.Enqueue(incomingPacket); 1612 if (incomingPacket.Packet.Type == PacketType.AgentUpdate ||
1613 incomingPacket.Packet.Type == PacketType.ChatFromViewer)
1614 packetInbox.EnqueueHigh(incomingPacket);
1615 else
1616 packetInbox.EnqueueLow(incomingPacket);
1574 } 1617 }
1575 1618
1576 #region BinaryStats 1619 #region BinaryStats
@@ -1722,6 +1765,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1722 if (!tp) 1765 if (!tp)
1723 client.SceneAgent.SendInitialDataToMe(); 1766 client.SceneAgent.SendInitialDataToMe();
1724 } 1767 }
1768
1769 // Now we know we can handle more data
1770 Thread.Sleep(200);
1771
1772 // Obtain the queue and remove it from the cache
1773 Queue<UDPPacketBuffer> queue = null;
1774
1775 lock (m_pendingCache)
1776 {
1777 if (!m_pendingCache.TryGetValue(endPoint, out queue))
1778 {
1779 m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present");
1780 return;
1781 }
1782 m_pendingCache.Remove(endPoint);
1783 }
1784
1785 m_log.DebugFormat("[LLUDPSERVER]: Client created, processing pending queue, {0} entries", queue.Count);
1786
1787 // Reinject queued packets
1788 while(queue.Count > 0)
1789 {
1790 UDPPacketBuffer buf = queue.Dequeue();
1791 PacketReceived(buf);
1792 }
1793 queue = null;
1725 } 1794 }
1726 else 1795 else
1727 { 1796 {
@@ -1729,6 +1798,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1729 m_log.WarnFormat( 1798 m_log.WarnFormat(
1730 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", 1799 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}",
1731 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint); 1800 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint);
1801 lock (m_pendingCache)
1802 m_pendingCache.Remove(endPoint);
1732 } 1803 }
1733 1804
1734 // m_log.DebugFormat( 1805 // m_log.DebugFormat(
@@ -1971,6 +2042,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1971 2042
1972 while (IsRunningInbound) 2043 while (IsRunningInbound)
1973 { 2044 {
2045 m_scene.ThreadAlive(1);
1974 try 2046 try
1975 { 2047 {
1976 IncomingPacket incomingPacket = null; 2048 IncomingPacket incomingPacket = null;
@@ -2020,6 +2092,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2020 2092
2021 while (base.IsRunningOutbound) 2093 while (base.IsRunningOutbound)
2022 { 2094 {
2095 m_scene.ThreadAlive(2);
2023 try 2096 try
2024 { 2097 {
2025 m_packetSent = false; 2098 m_packetSent = false;
@@ -2255,8 +2328,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2255 Packet packet = incomingPacket.Packet; 2328 Packet packet = incomingPacket.Packet;
2256 LLClientView client = incomingPacket.Client; 2329 LLClientView client = incomingPacket.Client;
2257 2330
2258 if (client.IsActive) 2331// if (client.IsActive)
2259 { 2332// {
2260 m_currentIncomingClient = client; 2333 m_currentIncomingClient = client;
2261 2334
2262 try 2335 try
@@ -2283,13 +2356,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2283 { 2356 {
2284 m_currentIncomingClient = null; 2357 m_currentIncomingClient = null;
2285 } 2358 }
2286 } 2359// }
2287 else 2360// else
2288 { 2361// {
2289 m_log.DebugFormat( 2362// m_log.DebugFormat(
2290 "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", 2363// "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}",
2291 packet.Type, client.Name, m_scene.RegionInfo.RegionName); 2364// packet.Type, client.Name, m_scene.RegionInfo.RegionName);
2292 } 2365// }
2293 2366
2294 IncomingPacketsProcessed++; 2367 IncomingPacketsProcessed++;
2295 } 2368 }
@@ -2305,4 +2378,4 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2305 } 2378 }
2306 } 2379 }
2307 } 2380 }
2308} \ No newline at end of file 2381}