diff options
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs')
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 122 |
1 files changed, 97 insertions, 25 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 8eb2e06..d008702 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | |||
@@ -121,7 +121,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
121 | /// <summary>Handlers for incoming packets</summary> | 121 | /// <summary>Handlers for incoming packets</summary> |
122 | //PacketEventDictionary packetEvents = new PacketEventDictionary(); | 122 | //PacketEventDictionary packetEvents = new PacketEventDictionary(); |
123 | /// <summary>Incoming packets that are awaiting handling</summary> | 123 | /// <summary>Incoming packets that are awaiting handling</summary> |
124 | private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>(); | 124 | //private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>(); |
125 | |||
126 | private DoubleQueue<IncomingPacket> packetInbox = new DoubleQueue<IncomingPacket>(); | ||
125 | 127 | ||
126 | /// <summary></summary> | 128 | /// <summary></summary> |
127 | //private UDPClientCollection m_clients = new UDPClientCollection(); | 129 | //private UDPClientCollection m_clients = new UDPClientCollection(); |
@@ -176,6 +178,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
176 | /// <summary>Flag to signal when clients should send pings</summary> | 178 | /// <summary>Flag to signal when clients should send pings</summary> |
177 | protected bool m_sendPing; | 179 | protected bool m_sendPing; |
178 | 180 | ||
181 | private ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>(); | ||
179 | private Pool<IncomingPacket> m_incomingPacketPool; | 182 | private Pool<IncomingPacket> m_incomingPacketPool; |
180 | 183 | ||
181 | /// <summary> | 184 | /// <summary> |
@@ -782,6 +785,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
782 | 785 | ||
783 | #region Queue or Send | 786 | #region Queue or Send |
784 | 787 | ||
788 | bool highPriority = false; | ||
789 | |||
790 | if (category != ThrottleOutPacketType.Unknown && (category & ThrottleOutPacketType.HighPriority) != 0) | ||
791 | { | ||
792 | category = (ThrottleOutPacketType)((int)category & 127); | ||
793 | highPriority = true; | ||
794 | } | ||
795 | |||
785 | OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null); | 796 | OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null); |
786 | // If we were not provided a method for handling unacked, use the UDPServer default method | 797 | // If we were not provided a method for handling unacked, use the UDPServer default method |
787 | outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method); | 798 | outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method); |
@@ -790,7 +801,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
790 | // continue to display the deleted object until relog. Therefore, we need to always queue a kill object | 801 | // continue to display the deleted object until relog. Therefore, we need to always queue a kill object |
791 | // packet so that it isn't sent before a queued update packet. | 802 | // packet so that it isn't sent before a queued update packet. |
792 | bool requestQueue = type == PacketType.KillObject; | 803 | bool requestQueue = type == PacketType.KillObject; |
793 | if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue)) | 804 | if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue, highPriority)) |
794 | SendPacketFinal(outgoingPacket); | 805 | SendPacketFinal(outgoingPacket); |
795 | 806 | ||
796 | #endregion Queue or Send | 807 | #endregion Queue or Send |
@@ -1075,21 +1086,46 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1075 | 1086 | ||
1076 | #region Packet to Client Mapping | 1087 | #region Packet to Client Mapping |
1077 | 1088 | ||
1078 | // UseCircuitCode handling | 1089 | // If there is already a client for this endpoint, don't process UseCircuitCode |
1079 | if (packet.Type == PacketType.UseCircuitCode) | 1090 | IClientAPI client = null; |
1091 | if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView)) | ||
1080 | { | 1092 | { |
1081 | // We need to copy the endpoint so that it doesn't get changed when another thread reuses the | 1093 | // UseCircuitCode handling |
1082 | // buffer. | 1094 | if (packet.Type == PacketType.UseCircuitCode) |
1083 | object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; | 1095 | { |
1096 | // And if there is a UseCircuitCode pending, also drop it | ||
1097 | lock (m_pendingCache) | ||
1098 | { | ||
1099 | if (m_pendingCache.Contains(endPoint)) | ||
1100 | return; | ||
1084 | 1101 | ||
1085 | Util.FireAndForget(HandleUseCircuitCode, array); | 1102 | m_pendingCache.AddOrUpdate(endPoint, new Queue<UDPPacketBuffer>(), 60); |
1103 | } | ||
1086 | 1104 | ||
1087 | return; | 1105 | // We need to copy the endpoint so that it doesn't get changed when another thread reuses the |
1106 | // buffer. | ||
1107 | object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; | ||
1108 | |||
1109 | Util.FireAndForget(HandleUseCircuitCode, array); | ||
1110 | |||
1111 | return; | ||
1112 | } | ||
1113 | } | ||
1114 | |||
1115 | // If this is a pending connection, enqueue, don't process yet | ||
1116 | lock (m_pendingCache) | ||
1117 | { | ||
1118 | Queue<UDPPacketBuffer> queue; | ||
1119 | if (m_pendingCache.TryGetValue(endPoint, out queue)) | ||
1120 | { | ||
1121 | //m_log.DebugFormat("[LLUDPSERVER]: Enqueued a {0} packet into the pending queue", packet.Type); | ||
1122 | queue.Enqueue(buffer); | ||
1123 | return; | ||
1124 | } | ||
1088 | } | 1125 | } |
1089 | 1126 | ||
1090 | // Determine which agent this packet came from | 1127 | // Determine which agent this packet came from |
1091 | IClientAPI client; | 1128 | if (client == null || !(client is LLClientView)) |
1092 | if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView)) | ||
1093 | { | 1129 | { |
1094 | //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); | 1130 | //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); |
1095 | return; | 1131 | return; |
@@ -1098,7 +1134,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1098 | udpClient = ((LLClientView)client).UDPClient; | 1134 | udpClient = ((LLClientView)client).UDPClient; |
1099 | 1135 | ||
1100 | if (!udpClient.IsConnected) | 1136 | if (!udpClient.IsConnected) |
1137 | { | ||
1138 | m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet for a unConnected client in " + m_scene.RegionInfo.RegionName); | ||
1101 | return; | 1139 | return; |
1140 | } | ||
1102 | 1141 | ||
1103 | #endregion Packet to Client Mapping | 1142 | #endregion Packet to Client Mapping |
1104 | 1143 | ||
@@ -1228,7 +1267,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1228 | incomingPacket = new IncomingPacket((LLClientView)client, packet); | 1267 | incomingPacket = new IncomingPacket((LLClientView)client, packet); |
1229 | } | 1268 | } |
1230 | 1269 | ||
1231 | packetInbox.Enqueue(incomingPacket); | 1270 | if (incomingPacket.Packet.Type == PacketType.AgentUpdate || |
1271 | incomingPacket.Packet.Type == PacketType.ChatFromViewer) | ||
1272 | packetInbox.EnqueueHigh(incomingPacket); | ||
1273 | else | ||
1274 | packetInbox.EnqueueLow(incomingPacket); | ||
1232 | } | 1275 | } |
1233 | 1276 | ||
1234 | #region BinaryStats | 1277 | #region BinaryStats |
@@ -1376,10 +1419,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1376 | { | 1419 | { |
1377 | AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(uccp.CircuitCode.Code); | 1420 | AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(uccp.CircuitCode.Code); |
1378 | bool tp = (aCircuit.teleportFlags > 0); | 1421 | bool tp = (aCircuit.teleportFlags > 0); |
1379 | // Let's delay this for TP agents, otherwise the viewer doesn't know where to get meshes from | ||
1380 | if (!tp) | 1422 | if (!tp) |
1381 | client.SceneAgent.SendInitialDataToMe(); | 1423 | client.SceneAgent.SendInitialDataToMe(); |
1382 | } | 1424 | } |
1425 | |||
1426 | // Now we know we can handle more data | ||
1427 | Thread.Sleep(200); | ||
1428 | |||
1429 | // Obtain the queue and remove it from the cache | ||
1430 | Queue<UDPPacketBuffer> queue = null; | ||
1431 | |||
1432 | lock (m_pendingCache) | ||
1433 | { | ||
1434 | if (!m_pendingCache.TryGetValue(endPoint, out queue)) | ||
1435 | { | ||
1436 | m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present"); | ||
1437 | return; | ||
1438 | } | ||
1439 | m_pendingCache.Remove(endPoint); | ||
1440 | } | ||
1441 | |||
1442 | m_log.DebugFormat("[LLUDPSERVER]: Client created, processing pending queue, {0} entries", queue.Count); | ||
1443 | |||
1444 | // Reinject queued packets | ||
1445 | while(queue.Count > 0) | ||
1446 | { | ||
1447 | UDPPacketBuffer buf = queue.Dequeue(); | ||
1448 | PacketReceived(buf); | ||
1449 | } | ||
1450 | queue = null; | ||
1383 | } | 1451 | } |
1384 | else | 1452 | else |
1385 | { | 1453 | { |
@@ -1387,6 +1455,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1387 | m_log.WarnFormat( | 1455 | m_log.WarnFormat( |
1388 | "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", | 1456 | "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", |
1389 | uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint); | 1457 | uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint); |
1458 | lock (m_pendingCache) | ||
1459 | m_pendingCache.Remove(endPoint); | ||
1390 | } | 1460 | } |
1391 | 1461 | ||
1392 | // m_log.DebugFormat( | 1462 | // m_log.DebugFormat( |
@@ -1505,7 +1575,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1505 | if (!client.SceneAgent.IsChildAgent) | 1575 | if (!client.SceneAgent.IsChildAgent) |
1506 | client.Kick("Simulator logged you out due to connection timeout"); | 1576 | client.Kick("Simulator logged you out due to connection timeout"); |
1507 | 1577 | ||
1508 | client.CloseWithoutChecks(); | 1578 | client.CloseWithoutChecks(true); |
1509 | } | 1579 | } |
1510 | } | 1580 | } |
1511 | 1581 | ||
@@ -1517,6 +1587,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1517 | 1587 | ||
1518 | while (IsRunningInbound) | 1588 | while (IsRunningInbound) |
1519 | { | 1589 | { |
1590 | m_scene.ThreadAlive(1); | ||
1520 | try | 1591 | try |
1521 | { | 1592 | { |
1522 | IncomingPacket incomingPacket = null; | 1593 | IncomingPacket incomingPacket = null; |
@@ -1564,6 +1635,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1564 | 1635 | ||
1565 | while (base.IsRunningOutbound) | 1636 | while (base.IsRunningOutbound) |
1566 | { | 1637 | { |
1638 | m_scene.ThreadAlive(2); | ||
1567 | try | 1639 | try |
1568 | { | 1640 | { |
1569 | m_packetSent = false; | 1641 | m_packetSent = false; |
@@ -1794,8 +1866,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1794 | Packet packet = incomingPacket.Packet; | 1866 | Packet packet = incomingPacket.Packet; |
1795 | LLClientView client = incomingPacket.Client; | 1867 | LLClientView client = incomingPacket.Client; |
1796 | 1868 | ||
1797 | if (client.IsActive) | 1869 | // if (client.IsActive) |
1798 | { | 1870 | // { |
1799 | m_currentIncomingClient = client; | 1871 | m_currentIncomingClient = client; |
1800 | 1872 | ||
1801 | try | 1873 | try |
@@ -1822,13 +1894,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1822 | { | 1894 | { |
1823 | m_currentIncomingClient = null; | 1895 | m_currentIncomingClient = null; |
1824 | } | 1896 | } |
1825 | } | 1897 | // } |
1826 | else | 1898 | // else |
1827 | { | 1899 | // { |
1828 | m_log.DebugFormat( | 1900 | // m_log.DebugFormat( |
1829 | "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", | 1901 | // "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", |
1830 | packet.Type, client.Name, m_scene.RegionInfo.RegionName); | 1902 | // packet.Type, client.Name, m_scene.RegionInfo.RegionName); |
1831 | } | 1903 | // } |
1832 | 1904 | ||
1833 | IncomingPacketsProcessed++; | 1905 | IncomingPacketsProcessed++; |
1834 | } | 1906 | } |
@@ -1840,8 +1912,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1840 | if (!client.IsLoggingOut) | 1912 | if (!client.IsLoggingOut) |
1841 | { | 1913 | { |
1842 | client.IsLoggingOut = true; | 1914 | client.IsLoggingOut = true; |
1843 | client.Close(); | 1915 | client.Close(false, false); |
1844 | } | 1916 | } |
1845 | } | 1917 | } |
1846 | } | 1918 | } |
1847 | } \ No newline at end of file | 1919 | } |