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, 98 insertions, 24 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 37fd252..7a4c6f4 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | |||
@@ -168,7 +168,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
168 | /// <summary>Handlers for incoming packets</summary> | 168 | /// <summary>Handlers for incoming packets</summary> |
169 | //PacketEventDictionary packetEvents = new PacketEventDictionary(); | 169 | //PacketEventDictionary packetEvents = new PacketEventDictionary(); |
170 | /// <summary>Incoming packets that are awaiting handling</summary> | 170 | /// <summary>Incoming packets that are awaiting handling</summary> |
171 | private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>(); | 171 | //private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>(); |
172 | |||
173 | private DoubleQueue<IncomingPacket> packetInbox = new DoubleQueue<IncomingPacket>(); | ||
172 | 174 | ||
173 | /// <summary></summary> | 175 | /// <summary></summary> |
174 | //private UDPClientCollection m_clients = new UDPClientCollection(); | 176 | //private UDPClientCollection m_clients = new UDPClientCollection(); |
@@ -223,6 +225,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
223 | /// <summary>Flag to signal when clients should send pings</summary> | 225 | /// <summary>Flag to signal when clients should send pings</summary> |
224 | protected bool m_sendPing; | 226 | protected bool m_sendPing; |
225 | 227 | ||
228 | private ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>(); | ||
229 | |||
226 | /// <summary> | 230 | /// <summary> |
227 | /// Event used to signal when queued packets are available for sending. | 231 | /// Event used to signal when queued packets are available for sending. |
228 | /// </summary> | 232 | /// </summary> |
@@ -961,6 +965,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
961 | 965 | ||
962 | #region Queue or Send | 966 | #region Queue or Send |
963 | 967 | ||
968 | bool highPriority = false; | ||
969 | |||
970 | if (category != ThrottleOutPacketType.Unknown && (category & ThrottleOutPacketType.HighPriority) != 0) | ||
971 | { | ||
972 | category = (ThrottleOutPacketType)((int)category & 127); | ||
973 | highPriority = true; | ||
974 | } | ||
975 | |||
964 | OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null); | 976 | OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null); |
965 | // If we were not provided a method for handling unacked, use the UDPServer default method | 977 | // If we were not provided a method for handling unacked, use the UDPServer default method |
966 | outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method); | 978 | outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method); |
@@ -969,7 +981,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
969 | // continue to display the deleted object until relog. Therefore, we need to always queue a kill object | 981 | // continue to display the deleted object until relog. Therefore, we need to always queue a kill object |
970 | // packet so that it isn't sent before a queued update packet. | 982 | // packet so that it isn't sent before a queued update packet. |
971 | bool requestQueue = type == PacketType.KillObject; | 983 | bool requestQueue = type == PacketType.KillObject; |
972 | if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue)) | 984 | if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue, highPriority)) |
973 | SendPacketFinal(outgoingPacket); | 985 | SendPacketFinal(outgoingPacket); |
974 | 986 | ||
975 | #endregion Queue or Send | 987 | #endregion Queue or Send |
@@ -1254,21 +1266,46 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1254 | 1266 | ||
1255 | #region Packet to Client Mapping | 1267 | #region Packet to Client Mapping |
1256 | 1268 | ||
1257 | // UseCircuitCode handling | 1269 | // If there is already a client for this endpoint, don't process UseCircuitCode |
1258 | if (packet.Type == PacketType.UseCircuitCode) | 1270 | IClientAPI client = null; |
1271 | if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView)) | ||
1259 | { | 1272 | { |
1260 | // We need to copy the endpoint so that it doesn't get changed when another thread reuses the | 1273 | // UseCircuitCode handling |
1261 | // buffer. | 1274 | if (packet.Type == PacketType.UseCircuitCode) |
1262 | object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; | 1275 | { |
1276 | // And if there is a UseCircuitCode pending, also drop it | ||
1277 | lock (m_pendingCache) | ||
1278 | { | ||
1279 | if (m_pendingCache.Contains(endPoint)) | ||
1280 | return; | ||
1281 | |||
1282 | m_pendingCache.AddOrUpdate(endPoint, new Queue<UDPPacketBuffer>(), 60); | ||
1283 | } | ||
1263 | 1284 | ||
1264 | Util.FireAndForget(HandleUseCircuitCode, array); | 1285 | // We need to copy the endpoint so that it doesn't get changed when another thread reuses the |
1286 | // buffer. | ||
1287 | object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; | ||
1265 | 1288 | ||
1266 | return; | 1289 | Util.FireAndForget(HandleUseCircuitCode, array); |
1290 | |||
1291 | return; | ||
1292 | } | ||
1293 | } | ||
1294 | |||
1295 | // If this is a pending connection, enqueue, don't process yet | ||
1296 | lock (m_pendingCache) | ||
1297 | { | ||
1298 | Queue<UDPPacketBuffer> queue; | ||
1299 | if (m_pendingCache.TryGetValue(endPoint, out queue)) | ||
1300 | { | ||
1301 | //m_log.DebugFormat("[LLUDPSERVER]: Enqueued a {0} packet into the pending queue", packet.Type); | ||
1302 | queue.Enqueue(buffer); | ||
1303 | return; | ||
1304 | } | ||
1267 | } | 1305 | } |
1268 | 1306 | ||
1269 | // Determine which agent this packet came from | 1307 | // Determine which agent this packet came from |
1270 | IClientAPI client; | 1308 | if (client == null || !(client is LLClientView)) |
1271 | if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView)) | ||
1272 | { | 1309 | { |
1273 | //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); | 1310 | //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); |
1274 | return; | 1311 | return; |
@@ -1277,7 +1314,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1277 | udpClient = ((LLClientView)client).UDPClient; | 1314 | udpClient = ((LLClientView)client).UDPClient; |
1278 | 1315 | ||
1279 | if (!udpClient.IsConnected) | 1316 | if (!udpClient.IsConnected) |
1317 | { | ||
1318 | m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet for a unConnected client in " + m_scene.RegionInfo.RegionName); | ||
1280 | return; | 1319 | return; |
1320 | } | ||
1281 | 1321 | ||
1282 | #endregion Packet to Client Mapping | 1322 | #endregion Packet to Client Mapping |
1283 | 1323 | ||
@@ -1426,7 +1466,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1426 | incomingPacket = new IncomingPacket((LLClientView)client, packet); | 1466 | incomingPacket = new IncomingPacket((LLClientView)client, packet); |
1427 | } | 1467 | } |
1428 | 1468 | ||
1429 | packetInbox.Enqueue(incomingPacket); | 1469 | if (incomingPacket.Packet.Type == PacketType.AgentUpdate || |
1470 | incomingPacket.Packet.Type == PacketType.ChatFromViewer) | ||
1471 | packetInbox.EnqueueHigh(incomingPacket); | ||
1472 | else | ||
1473 | packetInbox.EnqueueLow(incomingPacket); | ||
1430 | } | 1474 | } |
1431 | 1475 | ||
1432 | #region BinaryStats | 1476 | #region BinaryStats |
@@ -1578,6 +1622,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1578 | if (!tp) | 1622 | if (!tp) |
1579 | client.SceneAgent.SendInitialDataToMe(); | 1623 | client.SceneAgent.SendInitialDataToMe(); |
1580 | } | 1624 | } |
1625 | |||
1626 | // Now we know we can handle more data | ||
1627 | Thread.Sleep(200); | ||
1628 | |||
1629 | // Obtain the queue and remove it from the cache | ||
1630 | Queue<UDPPacketBuffer> queue = null; | ||
1631 | |||
1632 | lock (m_pendingCache) | ||
1633 | { | ||
1634 | if (!m_pendingCache.TryGetValue(endPoint, out queue)) | ||
1635 | { | ||
1636 | m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present"); | ||
1637 | return; | ||
1638 | } | ||
1639 | m_pendingCache.Remove(endPoint); | ||
1640 | } | ||
1641 | |||
1642 | m_log.DebugFormat("[LLUDPSERVER]: Client created, processing pending queue, {0} entries", queue.Count); | ||
1643 | |||
1644 | // Reinject queued packets | ||
1645 | while(queue.Count > 0) | ||
1646 | { | ||
1647 | UDPPacketBuffer buf = queue.Dequeue(); | ||
1648 | PacketReceived(buf); | ||
1649 | } | ||
1650 | queue = null; | ||
1581 | } | 1651 | } |
1582 | else | 1652 | else |
1583 | { | 1653 | { |
@@ -1585,6 +1655,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1585 | m_log.WarnFormat( | 1655 | m_log.WarnFormat( |
1586 | "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", | 1656 | "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", |
1587 | uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint); | 1657 | uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint); |
1658 | lock (m_pendingCache) | ||
1659 | m_pendingCache.Remove(endPoint); | ||
1588 | } | 1660 | } |
1589 | 1661 | ||
1590 | // m_log.DebugFormat( | 1662 | // m_log.DebugFormat( |
@@ -1704,7 +1776,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1704 | if (!client.SceneAgent.IsChildAgent) | 1776 | if (!client.SceneAgent.IsChildAgent) |
1705 | client.Kick("Simulator logged you out due to connection timeout"); | 1777 | client.Kick("Simulator logged you out due to connection timeout"); |
1706 | 1778 | ||
1707 | client.CloseWithoutChecks(); | 1779 | client.CloseWithoutChecks(true); |
1708 | } | 1780 | } |
1709 | } | 1781 | } |
1710 | 1782 | ||
@@ -1716,6 +1788,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1716 | 1788 | ||
1717 | while (IsRunningInbound) | 1789 | while (IsRunningInbound) |
1718 | { | 1790 | { |
1791 | m_scene.ThreadAlive(1); | ||
1719 | try | 1792 | try |
1720 | { | 1793 | { |
1721 | IncomingPacket incomingPacket = null; | 1794 | IncomingPacket incomingPacket = null; |
@@ -1765,6 +1838,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1765 | 1838 | ||
1766 | while (base.IsRunningOutbound) | 1839 | while (base.IsRunningOutbound) |
1767 | { | 1840 | { |
1841 | m_scene.ThreadAlive(2); | ||
1768 | try | 1842 | try |
1769 | { | 1843 | { |
1770 | m_packetSent = false; | 1844 | m_packetSent = false; |
@@ -1999,8 +2073,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1999 | Packet packet = incomingPacket.Packet; | 2073 | Packet packet = incomingPacket.Packet; |
2000 | LLClientView client = incomingPacket.Client; | 2074 | LLClientView client = incomingPacket.Client; |
2001 | 2075 | ||
2002 | if (client.IsActive) | 2076 | // if (client.IsActive) |
2003 | { | 2077 | // { |
2004 | m_currentIncomingClient = client; | 2078 | m_currentIncomingClient = client; |
2005 | 2079 | ||
2006 | try | 2080 | try |
@@ -2027,13 +2101,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2027 | { | 2101 | { |
2028 | m_currentIncomingClient = null; | 2102 | m_currentIncomingClient = null; |
2029 | } | 2103 | } |
2030 | } | 2104 | // } |
2031 | else | 2105 | // else |
2032 | { | 2106 | // { |
2033 | m_log.DebugFormat( | 2107 | // m_log.DebugFormat( |
2034 | "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", | 2108 | // "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", |
2035 | packet.Type, client.Name, m_scene.RegionInfo.RegionName); | 2109 | // packet.Type, client.Name, m_scene.RegionInfo.RegionName); |
2036 | } | 2110 | // } |
2037 | 2111 | ||
2038 | IncomingPacketsProcessed++; | 2112 | IncomingPacketsProcessed++; |
2039 | } | 2113 | } |
@@ -2045,8 +2119,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2045 | if (!client.IsLoggingOut) | 2119 | if (!client.IsLoggingOut) |
2046 | { | 2120 | { |
2047 | client.IsLoggingOut = true; | 2121 | client.IsLoggingOut = true; |
2048 | client.Close(); | 2122 | client.Close(false, false); |
2049 | } | 2123 | } |
2050 | } | 2124 | } |
2051 | } | 2125 | } |
2052 | } \ No newline at end of file | 2126 | } |