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 3bd1ef1..4854893 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -223,7 +223,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
223 /// <summary>Handlers for incoming packets</summary> 223 /// <summary>Handlers for incoming packets</summary>
224 //PacketEventDictionary packetEvents = new PacketEventDictionary(); 224 //PacketEventDictionary packetEvents = new PacketEventDictionary();
225 /// <summary>Incoming packets that are awaiting handling</summary> 225 /// <summary>Incoming packets that are awaiting handling</summary>
226 private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>(); 226 //private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>();
227
228 private DoubleQueue<IncomingPacket> packetInbox = new DoubleQueue<IncomingPacket>();
227 229
228 /// <summary></summary> 230 /// <summary></summary>
229 //private UDPClientCollection m_clients = new UDPClientCollection(); 231 //private UDPClientCollection m_clients = new UDPClientCollection();
@@ -278,6 +280,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
278 /// <summary>Flag to signal when clients should send pings</summary> 280 /// <summary>Flag to signal when clients should send pings</summary>
279 protected bool m_sendPing; 281 protected bool m_sendPing;
280 282
283 private ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>();
284
281 /// <summary> 285 /// <summary>
282 /// Event used to signal when queued packets are available for sending. 286 /// Event used to signal when queued packets are available for sending.
283 /// </summary> 287 /// </summary>
@@ -1040,6 +1044,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1040 1044
1041 #region Queue or Send 1045 #region Queue or Send
1042 1046
1047 bool highPriority = false;
1048
1049 if (category != ThrottleOutPacketType.Unknown && (category & ThrottleOutPacketType.HighPriority) != 0)
1050 {
1051 category = (ThrottleOutPacketType)((int)category & 127);
1052 highPriority = true;
1053 }
1054
1043 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null); 1055 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null);
1044 // If we were not provided a method for handling unacked, use the UDPServer default method 1056 // If we were not provided a method for handling unacked, use the UDPServer default method
1045 outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method); 1057 outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method);
@@ -1048,15 +1060,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1048 // continue to display the deleted object until relog. Therefore, we need to always queue a kill object 1060 // continue to display the deleted object until relog. Therefore, we need to always queue a kill object
1049 // packet so that it isn't sent before a queued update packet. 1061 // packet so that it isn't sent before a queued update packet.
1050 bool requestQueue = type == PacketType.KillObject; 1062 bool requestQueue = type == PacketType.KillObject;
1063 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue, highPriority))
1051 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue)) 1064 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue))
1052 { 1065 {
1053 SendPacketFinal(outgoingPacket); 1066 SendPacketFinal(outgoingPacket);
1054 return true; 1067 return true;
1055 } 1068 }
1056 else 1069
1057 { 1070 return false;
1058 return false;
1059 }
1060 1071
1061 #endregion Queue or Send 1072 #endregion Queue or Send
1062 } 1073 }
@@ -1354,34 +1365,59 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1354 1365
1355 #region Packet to Client Mapping 1366 #region Packet to Client Mapping
1356 1367
1357 // UseCircuitCode handling 1368 // If there is already a client for this endpoint, don't process UseCircuitCode
1358 if (packet.Type == PacketType.UseCircuitCode) 1369 IClientAPI client = null;
1370 if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
1359 { 1371 {
1360 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the 1372 // UseCircuitCode handling
1361 // buffer. 1373 if (packet.Type == PacketType.UseCircuitCode)
1362 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; 1374 {
1375 // And if there is a UseCircuitCode pending, also drop it
1376 lock (m_pendingCache)
1377 {
1378 if (m_pendingCache.Contains(endPoint))
1379 return;
1363 1380
1364 Util.FireAndForget(HandleUseCircuitCode, array); 1381 m_pendingCache.AddOrUpdate(endPoint, new Queue<UDPPacketBuffer>(), 60);
1382 }
1365 1383
1366 return; 1384 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the
1385 // buffer.
1386 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
1387
1388 Util.FireAndForget(HandleUseCircuitCode, array);
1389
1390 return;
1391 }
1367 } 1392 }
1368 else if (packet.Type == PacketType.CompleteAgentMovement) 1393
1394 // If this is a pending connection, enqueue, don't process yet
1395 lock (m_pendingCache)
1369 { 1396 {
1370 // Send ack straight away to let the viewer know that we got it. 1397 Queue<UDPPacketBuffer> queue;
1371 SendAckImmediate(endPoint, packet.Header.Sequence); 1398 if (m_pendingCache.TryGetValue(endPoint, out queue))
1399 {
1400 //m_log.DebugFormat("[LLUDPSERVER]: Enqueued a {0} packet into the pending queue", packet.Type);
1401 queue.Enqueue(buffer);
1402 return;
1403 }
1404 else if (packet.Type == PacketType.CompleteAgentMovement)
1405 {
1406 // Send ack straight away to let the viewer know that we got it.
1407 SendAckImmediate(endPoint, packet.Header.Sequence);
1372 1408
1373 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the 1409 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the
1374 // buffer. 1410 // buffer.
1375 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; 1411 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
1376 1412
1377 Util.FireAndForget(HandleCompleteMovementIntoRegion, array); 1413 Util.FireAndForget(HandleCompleteMovementIntoRegion, array);
1378 1414
1379 return; 1415 return;
1416 }
1380 } 1417 }
1381 1418
1382 // Determine which agent this packet came from 1419 // Determine which agent this packet came from
1383 IClientAPI client; 1420 if (client == null || !(client is LLClientView))
1384 if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
1385 { 1421 {
1386 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); 1422 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName);
1387 1423
@@ -1398,7 +1434,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1398 udpClient = ((LLClientView)client).UDPClient; 1434 udpClient = ((LLClientView)client).UDPClient;
1399 1435
1400 if (!udpClient.IsConnected) 1436 if (!udpClient.IsConnected)
1437 {
1438 m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet for a unConnected client in " + m_scene.RegionInfo.RegionName);
1401 return; 1439 return;
1440 }
1402 1441
1403 #endregion Packet to Client Mapping 1442 #endregion Packet to Client Mapping
1404 1443
@@ -1547,7 +1586,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1547 incomingPacket = new IncomingPacket((LLClientView)client, packet); 1586 incomingPacket = new IncomingPacket((LLClientView)client, packet);
1548 } 1587 }
1549 1588
1550 packetInbox.Enqueue(incomingPacket); 1589 if (incomingPacket.Packet.Type == PacketType.AgentUpdate ||
1590 incomingPacket.Packet.Type == PacketType.ChatFromViewer)
1591 packetInbox.EnqueueHigh(incomingPacket);
1592 else
1593 packetInbox.EnqueueLow(incomingPacket);
1551 } 1594 }
1552 1595
1553 #region BinaryStats 1596 #region BinaryStats
@@ -1699,6 +1742,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1699 if (!tp) 1742 if (!tp)
1700 client.SceneAgent.SendInitialDataToMe(); 1743 client.SceneAgent.SendInitialDataToMe();
1701 } 1744 }
1745
1746 // Now we know we can handle more data
1747 Thread.Sleep(200);
1748
1749 // Obtain the queue and remove it from the cache
1750 Queue<UDPPacketBuffer> queue = null;
1751
1752 lock (m_pendingCache)
1753 {
1754 if (!m_pendingCache.TryGetValue(endPoint, out queue))
1755 {
1756 m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present");
1757 return;
1758 }
1759 m_pendingCache.Remove(endPoint);
1760 }
1761
1762 m_log.DebugFormat("[LLUDPSERVER]: Client created, processing pending queue, {0} entries", queue.Count);
1763
1764 // Reinject queued packets
1765 while(queue.Count > 0)
1766 {
1767 UDPPacketBuffer buf = queue.Dequeue();
1768 PacketReceived(buf);
1769 }
1770 queue = null;
1702 } 1771 }
1703 else 1772 else
1704 { 1773 {
@@ -1706,6 +1775,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1706 m_log.WarnFormat( 1775 m_log.WarnFormat(
1707 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", 1776 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}",
1708 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint); 1777 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint);
1778 lock (m_pendingCache)
1779 m_pendingCache.Remove(endPoint);
1709 } 1780 }
1710 1781
1711 // m_log.DebugFormat( 1782 // m_log.DebugFormat(
@@ -1948,6 +2019,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1948 2019
1949 while (IsRunningInbound) 2020 while (IsRunningInbound)
1950 { 2021 {
2022 m_scene.ThreadAlive(1);
1951 try 2023 try
1952 { 2024 {
1953 IncomingPacket incomingPacket = null; 2025 IncomingPacket incomingPacket = null;
@@ -1997,6 +2069,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1997 2069
1998 while (base.IsRunningOutbound) 2070 while (base.IsRunningOutbound)
1999 { 2071 {
2072 m_scene.ThreadAlive(2);
2000 try 2073 try
2001 { 2074 {
2002 m_packetSent = false; 2075 m_packetSent = false;
@@ -2232,8 +2305,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2232 Packet packet = incomingPacket.Packet; 2305 Packet packet = incomingPacket.Packet;
2233 LLClientView client = incomingPacket.Client; 2306 LLClientView client = incomingPacket.Client;
2234 2307
2235 if (client.IsActive) 2308// if (client.IsActive)
2236 { 2309// {
2237 m_currentIncomingClient = client; 2310 m_currentIncomingClient = client;
2238 2311
2239 try 2312 try
@@ -2260,13 +2333,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2260 { 2333 {
2261 m_currentIncomingClient = null; 2334 m_currentIncomingClient = null;
2262 } 2335 }
2263 } 2336// }
2264 else 2337// else
2265 { 2338// {
2266 m_log.DebugFormat( 2339// m_log.DebugFormat(
2267 "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", 2340// "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}",
2268 packet.Type, client.Name, m_scene.RegionInfo.RegionName); 2341// packet.Type, client.Name, m_scene.RegionInfo.RegionName);
2269 } 2342// }
2270 2343
2271 IncomingPacketsProcessed++; 2344 IncomingPacketsProcessed++;
2272 } 2345 }
@@ -2282,4 +2355,4 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2282 } 2355 }
2283 } 2356 }
2284 } 2357 }
2285} \ No newline at end of file 2358}