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 985aa4d..33ca08c 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 |
@@ -1374,6 +1417,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1374 | // We only want to send initial data to new clients, not ones which are being converted from child to root. | 1417 | // We only want to send initial data to new clients, not ones which are being converted from child to root. |
1375 | if (client != null) | 1418 | if (client != null) |
1376 | client.SceneAgent.SendInitialDataToMe(); | 1419 | client.SceneAgent.SendInitialDataToMe(); |
1420 | |||
1421 | // Now we know we can handle more data | ||
1422 | Thread.Sleep(200); | ||
1423 | |||
1424 | // Obtain the queue and remove it from the cache | ||
1425 | Queue<UDPPacketBuffer> queue = null; | ||
1426 | |||
1427 | lock (m_pendingCache) | ||
1428 | { | ||
1429 | if (!m_pendingCache.TryGetValue(endPoint, out queue)) | ||
1430 | { | ||
1431 | m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present"); | ||
1432 | return; | ||
1433 | } | ||
1434 | m_pendingCache.Remove(endPoint); | ||
1435 | } | ||
1436 | |||
1437 | m_log.DebugFormat("[LLUDPSERVER]: Client created, processing pending queue, {0} entries", queue.Count); | ||
1438 | |||
1439 | // Reinject queued packets | ||
1440 | while(queue.Count > 0) | ||
1441 | { | ||
1442 | UDPPacketBuffer buf = queue.Dequeue(); | ||
1443 | PacketReceived(buf); | ||
1444 | } | ||
1445 | queue = null; | ||
1377 | } | 1446 | } |
1378 | else | 1447 | else |
1379 | { | 1448 | { |
@@ -1381,6 +1450,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1381 | m_log.WarnFormat( | 1450 | m_log.WarnFormat( |
1382 | "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", | 1451 | "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", |
1383 | uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint); | 1452 | uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint); |
1453 | lock (m_pendingCache) | ||
1454 | m_pendingCache.Remove(endPoint); | ||
1384 | } | 1455 | } |
1385 | 1456 | ||
1386 | // m_log.DebugFormat( | 1457 | // m_log.DebugFormat( |
@@ -1499,7 +1570,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1499 | if (!client.SceneAgent.IsChildAgent) | 1570 | if (!client.SceneAgent.IsChildAgent) |
1500 | client.Kick("Simulator logged you out due to connection timeout"); | 1571 | client.Kick("Simulator logged you out due to connection timeout"); |
1501 | 1572 | ||
1502 | client.CloseWithoutChecks(); | 1573 | client.CloseWithoutChecks(true); |
1503 | } | 1574 | } |
1504 | } | 1575 | } |
1505 | 1576 | ||
@@ -1511,6 +1582,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1511 | 1582 | ||
1512 | while (IsRunningInbound) | 1583 | while (IsRunningInbound) |
1513 | { | 1584 | { |
1585 | m_scene.ThreadAlive(1); | ||
1514 | try | 1586 | try |
1515 | { | 1587 | { |
1516 | IncomingPacket incomingPacket = null; | 1588 | IncomingPacket incomingPacket = null; |
@@ -1558,6 +1630,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1558 | 1630 | ||
1559 | while (base.IsRunningOutbound) | 1631 | while (base.IsRunningOutbound) |
1560 | { | 1632 | { |
1633 | m_scene.ThreadAlive(2); | ||
1561 | try | 1634 | try |
1562 | { | 1635 | { |
1563 | m_packetSent = false; | 1636 | m_packetSent = false; |
@@ -1788,8 +1861,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1788 | Packet packet = incomingPacket.Packet; | 1861 | Packet packet = incomingPacket.Packet; |
1789 | LLClientView client = incomingPacket.Client; | 1862 | LLClientView client = incomingPacket.Client; |
1790 | 1863 | ||
1791 | if (client.IsActive) | 1864 | // if (client.IsActive) |
1792 | { | 1865 | // { |
1793 | m_currentIncomingClient = client; | 1866 | m_currentIncomingClient = client; |
1794 | 1867 | ||
1795 | try | 1868 | try |
@@ -1816,13 +1889,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1816 | { | 1889 | { |
1817 | m_currentIncomingClient = null; | 1890 | m_currentIncomingClient = null; |
1818 | } | 1891 | } |
1819 | } | 1892 | // } |
1820 | else | 1893 | // else |
1821 | { | 1894 | // { |
1822 | m_log.DebugFormat( | 1895 | // m_log.DebugFormat( |
1823 | "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", | 1896 | // "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", |
1824 | packet.Type, client.Name, m_scene.RegionInfo.RegionName); | 1897 | // packet.Type, client.Name, m_scene.RegionInfo.RegionName); |
1825 | } | 1898 | // } |
1826 | 1899 | ||
1827 | IncomingPacketsProcessed++; | 1900 | IncomingPacketsProcessed++; |
1828 | } | 1901 | } |
@@ -1834,8 +1907,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1834 | if (!client.IsLoggingOut) | 1907 | if (!client.IsLoggingOut) |
1835 | { | 1908 | { |
1836 | client.IsLoggingOut = true; | 1909 | client.IsLoggingOut = true; |
1837 | client.Close(); | 1910 | client.Close(false, false); |
1838 | } | 1911 | } |
1839 | } | 1912 | } |
1840 | } | 1913 | } |
1841 | } \ No newline at end of file | 1914 | } |