diff options
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs')
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 121 |
1 files changed, 97 insertions, 24 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 72516cd..4154ef2 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | |||
@@ -126,7 +126,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
126 | /// <summary>Handlers for incoming packets</summary> | 126 | /// <summary>Handlers for incoming packets</summary> |
127 | //PacketEventDictionary packetEvents = new PacketEventDictionary(); | 127 | //PacketEventDictionary packetEvents = new PacketEventDictionary(); |
128 | /// <summary>Incoming packets that are awaiting handling</summary> | 128 | /// <summary>Incoming packets that are awaiting handling</summary> |
129 | private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>(); | 129 | //private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>(); |
130 | |||
131 | private DoubleQueue<IncomingPacket> packetInbox = new DoubleQueue<IncomingPacket>(); | ||
130 | 132 | ||
131 | /// <summary></summary> | 133 | /// <summary></summary> |
132 | //private UDPClientCollection m_clients = new UDPClientCollection(); | 134 | //private UDPClientCollection m_clients = new UDPClientCollection(); |
@@ -181,6 +183,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
181 | /// <summary>Flag to signal when clients should send pings</summary> | 183 | /// <summary>Flag to signal when clients should send pings</summary> |
182 | protected bool m_sendPing; | 184 | protected bool m_sendPing; |
183 | 185 | ||
186 | private ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>(); | ||
184 | private Pool<IncomingPacket> m_incomingPacketPool; | 187 | private Pool<IncomingPacket> m_incomingPacketPool; |
185 | 188 | ||
186 | /// <summary> | 189 | /// <summary> |
@@ -787,6 +790,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
787 | 790 | ||
788 | #region Queue or Send | 791 | #region Queue or Send |
789 | 792 | ||
793 | bool highPriority = false; | ||
794 | |||
795 | if (category != ThrottleOutPacketType.Unknown && (category & ThrottleOutPacketType.HighPriority) != 0) | ||
796 | { | ||
797 | category = (ThrottleOutPacketType)((int)category & 127); | ||
798 | highPriority = true; | ||
799 | } | ||
800 | |||
790 | OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null); | 801 | OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null); |
791 | // If we were not provided a method for handling unacked, use the UDPServer default method | 802 | // If we were not provided a method for handling unacked, use the UDPServer default method |
792 | outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method); | 803 | outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method); |
@@ -795,7 +806,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
795 | // continue to display the deleted object until relog. Therefore, we need to always queue a kill object | 806 | // continue to display the deleted object until relog. Therefore, we need to always queue a kill object |
796 | // packet so that it isn't sent before a queued update packet. | 807 | // packet so that it isn't sent before a queued update packet. |
797 | bool requestQueue = type == PacketType.KillObject; | 808 | bool requestQueue = type == PacketType.KillObject; |
798 | if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue)) | 809 | if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue, highPriority)) |
799 | SendPacketFinal(outgoingPacket); | 810 | SendPacketFinal(outgoingPacket); |
800 | 811 | ||
801 | #endregion Queue or Send | 812 | #endregion Queue or Send |
@@ -1080,21 +1091,46 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1080 | 1091 | ||
1081 | #region Packet to Client Mapping | 1092 | #region Packet to Client Mapping |
1082 | 1093 | ||
1083 | // UseCircuitCode handling | 1094 | // If there is already a client for this endpoint, don't process UseCircuitCode |
1084 | if (packet.Type == PacketType.UseCircuitCode) | 1095 | IClientAPI client = null; |
1096 | if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView)) | ||
1085 | { | 1097 | { |
1086 | // We need to copy the endpoint so that it doesn't get changed when another thread reuses the | 1098 | // UseCircuitCode handling |
1087 | // buffer. | 1099 | if (packet.Type == PacketType.UseCircuitCode) |
1088 | object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; | 1100 | { |
1101 | // And if there is a UseCircuitCode pending, also drop it | ||
1102 | lock (m_pendingCache) | ||
1103 | { | ||
1104 | if (m_pendingCache.Contains(endPoint)) | ||
1105 | return; | ||
1089 | 1106 | ||
1090 | Util.FireAndForget(HandleUseCircuitCode, array); | 1107 | m_pendingCache.AddOrUpdate(endPoint, new Queue<UDPPacketBuffer>(), 60); |
1108 | } | ||
1091 | 1109 | ||
1092 | return; | 1110 | // We need to copy the endpoint so that it doesn't get changed when another thread reuses the |
1111 | // buffer. | ||
1112 | object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; | ||
1113 | |||
1114 | Util.FireAndForget(HandleUseCircuitCode, array); | ||
1115 | |||
1116 | return; | ||
1117 | } | ||
1118 | } | ||
1119 | |||
1120 | // If this is a pending connection, enqueue, don't process yet | ||
1121 | lock (m_pendingCache) | ||
1122 | { | ||
1123 | Queue<UDPPacketBuffer> queue; | ||
1124 | if (m_pendingCache.TryGetValue(endPoint, out queue)) | ||
1125 | { | ||
1126 | //m_log.DebugFormat("[LLUDPSERVER]: Enqueued a {0} packet into the pending queue", packet.Type); | ||
1127 | queue.Enqueue(buffer); | ||
1128 | return; | ||
1129 | } | ||
1093 | } | 1130 | } |
1094 | 1131 | ||
1095 | // Determine which agent this packet came from | 1132 | // Determine which agent this packet came from |
1096 | IClientAPI client; | 1133 | if (client == null || !(client is LLClientView)) |
1097 | if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView)) | ||
1098 | { | 1134 | { |
1099 | //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); | 1135 | //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); |
1100 | return; | 1136 | return; |
@@ -1103,7 +1139,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1103 | udpClient = ((LLClientView)client).UDPClient; | 1139 | udpClient = ((LLClientView)client).UDPClient; |
1104 | 1140 | ||
1105 | if (!udpClient.IsConnected) | 1141 | if (!udpClient.IsConnected) |
1142 | { | ||
1143 | m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet for a unConnected client in " + m_scene.RegionInfo.RegionName); | ||
1106 | return; | 1144 | return; |
1145 | } | ||
1107 | 1146 | ||
1108 | #endregion Packet to Client Mapping | 1147 | #endregion Packet to Client Mapping |
1109 | 1148 | ||
@@ -1233,7 +1272,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1233 | incomingPacket = new IncomingPacket((LLClientView)client, packet); | 1272 | incomingPacket = new IncomingPacket((LLClientView)client, packet); |
1234 | } | 1273 | } |
1235 | 1274 | ||
1236 | packetInbox.Enqueue(incomingPacket); | 1275 | if (incomingPacket.Packet.Type == PacketType.AgentUpdate || |
1276 | incomingPacket.Packet.Type == PacketType.ChatFromViewer) | ||
1277 | packetInbox.EnqueueHigh(incomingPacket); | ||
1278 | else | ||
1279 | packetInbox.EnqueueLow(incomingPacket); | ||
1237 | } | 1280 | } |
1238 | 1281 | ||
1239 | #region BinaryStats | 1282 | #region BinaryStats |
@@ -1379,6 +1422,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1379 | // We only want to send initial data to new clients, not ones which are being converted from child to root. | 1422 | // We only want to send initial data to new clients, not ones which are being converted from child to root. |
1380 | if (client != null) | 1423 | if (client != null) |
1381 | client.SceneAgent.SendInitialDataToMe(); | 1424 | client.SceneAgent.SendInitialDataToMe(); |
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; | ||
1382 | } | 1451 | } |
1383 | else | 1452 | else |
1384 | { | 1453 | { |
@@ -1386,6 +1455,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1386 | m_log.WarnFormat( | 1455 | m_log.WarnFormat( |
1387 | "[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}", |
1388 | 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); | ||
1389 | } | 1460 | } |
1390 | 1461 | ||
1391 | // m_log.DebugFormat( | 1462 | // m_log.DebugFormat( |
@@ -1504,7 +1575,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1504 | if (!client.SceneAgent.IsChildAgent) | 1575 | if (!client.SceneAgent.IsChildAgent) |
1505 | client.Kick("Simulator logged you out due to connection timeout"); | 1576 | client.Kick("Simulator logged you out due to connection timeout"); |
1506 | 1577 | ||
1507 | client.CloseWithoutChecks(); | 1578 | client.CloseWithoutChecks(true); |
1508 | } | 1579 | } |
1509 | } | 1580 | } |
1510 | 1581 | ||
@@ -1516,6 +1587,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1516 | 1587 | ||
1517 | while (IsRunningInbound) | 1588 | while (IsRunningInbound) |
1518 | { | 1589 | { |
1590 | m_scene.ThreadAlive(1); | ||
1519 | try | 1591 | try |
1520 | { | 1592 | { |
1521 | IncomingPacket incomingPacket = null; | 1593 | IncomingPacket incomingPacket = null; |
@@ -1563,6 +1635,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1563 | 1635 | ||
1564 | while (base.IsRunningOutbound) | 1636 | while (base.IsRunningOutbound) |
1565 | { | 1637 | { |
1638 | m_scene.ThreadAlive(2); | ||
1566 | try | 1639 | try |
1567 | { | 1640 | { |
1568 | m_packetSent = false; | 1641 | m_packetSent = false; |
@@ -1793,8 +1866,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1793 | Packet packet = incomingPacket.Packet; | 1866 | Packet packet = incomingPacket.Packet; |
1794 | LLClientView client = incomingPacket.Client; | 1867 | LLClientView client = incomingPacket.Client; |
1795 | 1868 | ||
1796 | if (client.IsActive) | 1869 | // if (client.IsActive) |
1797 | { | 1870 | // { |
1798 | m_currentIncomingClient = client; | 1871 | m_currentIncomingClient = client; |
1799 | 1872 | ||
1800 | try | 1873 | try |
@@ -1821,13 +1894,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1821 | { | 1894 | { |
1822 | m_currentIncomingClient = null; | 1895 | m_currentIncomingClient = null; |
1823 | } | 1896 | } |
1824 | } | 1897 | // } |
1825 | else | 1898 | // else |
1826 | { | 1899 | // { |
1827 | m_log.DebugFormat( | 1900 | // m_log.DebugFormat( |
1828 | "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", | 1901 | // "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", |
1829 | packet.Type, client.Name, m_scene.RegionInfo.RegionName); | 1902 | // packet.Type, client.Name, m_scene.RegionInfo.RegionName); |
1830 | } | 1903 | // } |
1831 | 1904 | ||
1832 | IncomingPacketsProcessed++; | 1905 | IncomingPacketsProcessed++; |
1833 | } | 1906 | } |
@@ -1839,8 +1912,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1839 | if (!client.IsLoggingOut) | 1912 | if (!client.IsLoggingOut) |
1840 | { | 1913 | { |
1841 | client.IsLoggingOut = true; | 1914 | client.IsLoggingOut = true; |
1842 | client.Close(); | 1915 | client.Close(false, false); |
1843 | } | 1916 | } |
1844 | } | 1917 | } |
1845 | } | 1918 | } |
1846 | } \ No newline at end of file | 1919 | } |