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 a7628d2..d49f1f7 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> |
@@ -800,6 +803,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
800 | 803 | ||
801 | #region Queue or Send | 804 | #region Queue or Send |
802 | 805 | ||
806 | bool highPriority = false; | ||
807 | |||
808 | if (category != ThrottleOutPacketType.Unknown && (category & ThrottleOutPacketType.HighPriority) != 0) | ||
809 | { | ||
810 | category = (ThrottleOutPacketType)((int)category & 127); | ||
811 | highPriority = true; | ||
812 | } | ||
813 | |||
803 | OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null); | 814 | OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null); |
804 | // If we were not provided a method for handling unacked, use the UDPServer default method | 815 | // If we were not provided a method for handling unacked, use the UDPServer default method |
805 | outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method); | 816 | outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method); |
@@ -808,7 +819,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
808 | // continue to display the deleted object until relog. Therefore, we need to always queue a kill object | 819 | // continue to display the deleted object until relog. Therefore, we need to always queue a kill object |
809 | // packet so that it isn't sent before a queued update packet. | 820 | // packet so that it isn't sent before a queued update packet. |
810 | bool requestQueue = type == PacketType.KillObject; | 821 | bool requestQueue = type == PacketType.KillObject; |
811 | if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue)) | 822 | if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue, highPriority)) |
812 | SendPacketFinal(outgoingPacket); | 823 | SendPacketFinal(outgoingPacket); |
813 | 824 | ||
814 | #endregion Queue or Send | 825 | #endregion Queue or Send |
@@ -1093,21 +1104,46 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1093 | 1104 | ||
1094 | #region Packet to Client Mapping | 1105 | #region Packet to Client Mapping |
1095 | 1106 | ||
1096 | // UseCircuitCode handling | 1107 | // If there is already a client for this endpoint, don't process UseCircuitCode |
1097 | if (packet.Type == PacketType.UseCircuitCode) | 1108 | IClientAPI client = null; |
1109 | if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView)) | ||
1098 | { | 1110 | { |
1099 | // We need to copy the endpoint so that it doesn't get changed when another thread reuses the | 1111 | // UseCircuitCode handling |
1100 | // buffer. | 1112 | if (packet.Type == PacketType.UseCircuitCode) |
1101 | object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; | 1113 | { |
1114 | // And if there is a UseCircuitCode pending, also drop it | ||
1115 | lock (m_pendingCache) | ||
1116 | { | ||
1117 | if (m_pendingCache.Contains(endPoint)) | ||
1118 | return; | ||
1102 | 1119 | ||
1103 | Util.FireAndForget(HandleUseCircuitCode, array); | 1120 | m_pendingCache.AddOrUpdate(endPoint, new Queue<UDPPacketBuffer>(), 60); |
1121 | } | ||
1104 | 1122 | ||
1105 | return; | 1123 | // We need to copy the endpoint so that it doesn't get changed when another thread reuses the |
1124 | // buffer. | ||
1125 | object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; | ||
1126 | |||
1127 | Util.FireAndForget(HandleUseCircuitCode, array); | ||
1128 | |||
1129 | return; | ||
1130 | } | ||
1131 | } | ||
1132 | |||
1133 | // If this is a pending connection, enqueue, don't process yet | ||
1134 | lock (m_pendingCache) | ||
1135 | { | ||
1136 | Queue<UDPPacketBuffer> queue; | ||
1137 | if (m_pendingCache.TryGetValue(endPoint, out queue)) | ||
1138 | { | ||
1139 | //m_log.DebugFormat("[LLUDPSERVER]: Enqueued a {0} packet into the pending queue", packet.Type); | ||
1140 | queue.Enqueue(buffer); | ||
1141 | return; | ||
1142 | } | ||
1106 | } | 1143 | } |
1107 | 1144 | ||
1108 | // Determine which agent this packet came from | 1145 | // Determine which agent this packet came from |
1109 | IClientAPI client; | 1146 | if (client == null || !(client is LLClientView)) |
1110 | if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView)) | ||
1111 | { | 1147 | { |
1112 | //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); | 1148 | //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); |
1113 | return; | 1149 | return; |
@@ -1116,7 +1152,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1116 | udpClient = ((LLClientView)client).UDPClient; | 1152 | udpClient = ((LLClientView)client).UDPClient; |
1117 | 1153 | ||
1118 | if (!udpClient.IsConnected) | 1154 | if (!udpClient.IsConnected) |
1155 | { | ||
1156 | // m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet for a unConnected client in " + m_scene.RegionInfo.RegionName); | ||
1119 | return; | 1157 | return; |
1158 | } | ||
1120 | 1159 | ||
1121 | #endregion Packet to Client Mapping | 1160 | #endregion Packet to Client Mapping |
1122 | 1161 | ||
@@ -1246,7 +1285,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1246 | incomingPacket = new IncomingPacket((LLClientView)client, packet); | 1285 | incomingPacket = new IncomingPacket((LLClientView)client, packet); |
1247 | } | 1286 | } |
1248 | 1287 | ||
1249 | packetInbox.Enqueue(incomingPacket); | 1288 | if (incomingPacket.Packet.Type == PacketType.AgentUpdate || |
1289 | incomingPacket.Packet.Type == PacketType.ChatFromViewer) | ||
1290 | packetInbox.EnqueueHigh(incomingPacket); | ||
1291 | else | ||
1292 | packetInbox.EnqueueLow(incomingPacket); | ||
1250 | } | 1293 | } |
1251 | 1294 | ||
1252 | #region BinaryStats | 1295 | #region BinaryStats |
@@ -1366,6 +1409,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1366 | // We only want to send initial data to new clients, not ones which are being converted from child to root. | 1409 | // We only want to send initial data to new clients, not ones which are being converted from child to root. |
1367 | if (client != null) | 1410 | if (client != null) |
1368 | client.SceneAgent.SendInitialDataToMe(); | 1411 | client.SceneAgent.SendInitialDataToMe(); |
1412 | |||
1413 | // Now we know we can handle more data | ||
1414 | Thread.Sleep(200); | ||
1415 | |||
1416 | // Obtain the queue and remove it from the cache | ||
1417 | Queue<UDPPacketBuffer> queue = null; | ||
1418 | |||
1419 | lock (m_pendingCache) | ||
1420 | { | ||
1421 | if (!m_pendingCache.TryGetValue(endPoint, out queue)) | ||
1422 | { | ||
1423 | m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present"); | ||
1424 | return; | ||
1425 | } | ||
1426 | m_pendingCache.Remove(endPoint); | ||
1427 | } | ||
1428 | |||
1429 | m_log.DebugFormat("[LLUDPSERVER]: Client created, processing pending queue, {0} entries", queue.Count); | ||
1430 | |||
1431 | // Reinject queued packets | ||
1432 | while(queue.Count > 0) | ||
1433 | { | ||
1434 | UDPPacketBuffer buf = queue.Dequeue(); | ||
1435 | PacketReceived(buf); | ||
1436 | } | ||
1437 | queue = null; | ||
1369 | } | 1438 | } |
1370 | else | 1439 | else |
1371 | { | 1440 | { |
@@ -1373,6 +1442,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1373 | m_log.WarnFormat( | 1442 | m_log.WarnFormat( |
1374 | "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", | 1443 | "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", |
1375 | uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint); | 1444 | uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint); |
1445 | lock (m_pendingCache) | ||
1446 | m_pendingCache.Remove(endPoint); | ||
1376 | } | 1447 | } |
1377 | 1448 | ||
1378 | // m_log.DebugFormat( | 1449 | // m_log.DebugFormat( |
@@ -1491,7 +1562,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1491 | if (!client.SceneAgent.IsChildAgent) | 1562 | if (!client.SceneAgent.IsChildAgent) |
1492 | client.Kick("Simulator logged you out due to connection timeout"); | 1563 | client.Kick("Simulator logged you out due to connection timeout"); |
1493 | 1564 | ||
1494 | client.CloseWithoutChecks(); | 1565 | client.CloseWithoutChecks(true); |
1495 | } | 1566 | } |
1496 | } | 1567 | } |
1497 | 1568 | ||
@@ -1503,6 +1574,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1503 | 1574 | ||
1504 | while (IsRunningInbound) | 1575 | while (IsRunningInbound) |
1505 | { | 1576 | { |
1577 | m_scene.ThreadAlive(1); | ||
1506 | try | 1578 | try |
1507 | { | 1579 | { |
1508 | IncomingPacket incomingPacket = null; | 1580 | IncomingPacket incomingPacket = null; |
@@ -1550,6 +1622,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1550 | 1622 | ||
1551 | while (base.IsRunningOutbound) | 1623 | while (base.IsRunningOutbound) |
1552 | { | 1624 | { |
1625 | m_scene.ThreadAlive(2); | ||
1553 | try | 1626 | try |
1554 | { | 1627 | { |
1555 | m_packetSent = false; | 1628 | m_packetSent = false; |
@@ -1780,8 +1853,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1780 | Packet packet = incomingPacket.Packet; | 1853 | Packet packet = incomingPacket.Packet; |
1781 | LLClientView client = incomingPacket.Client; | 1854 | LLClientView client = incomingPacket.Client; |
1782 | 1855 | ||
1783 | if (client.IsActive) | 1856 | // if (client.IsActive) |
1784 | { | 1857 | // { |
1785 | m_currentIncomingClient = client; | 1858 | m_currentIncomingClient = client; |
1786 | 1859 | ||
1787 | try | 1860 | try |
@@ -1808,13 +1881,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1808 | { | 1881 | { |
1809 | m_currentIncomingClient = null; | 1882 | m_currentIncomingClient = null; |
1810 | } | 1883 | } |
1811 | } | 1884 | // } |
1812 | else | 1885 | // else |
1813 | { | 1886 | // { |
1814 | m_log.DebugFormat( | 1887 | // m_log.DebugFormat( |
1815 | "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", | 1888 | // "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", |
1816 | packet.Type, client.Name, m_scene.RegionInfo.RegionName); | 1889 | // packet.Type, client.Name, m_scene.RegionInfo.RegionName); |
1817 | } | 1890 | // } |
1818 | 1891 | ||
1819 | IncomingPacketsProcessed++; | 1892 | IncomingPacketsProcessed++; |
1820 | } | 1893 | } |
@@ -1826,8 +1899,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1826 | if (!client.IsLoggingOut) | 1899 | if (!client.IsLoggingOut) |
1827 | { | 1900 | { |
1828 | client.IsLoggingOut = true; | 1901 | client.IsLoggingOut = true; |
1829 | client.Close(); | 1902 | client.Close(false, false); |
1830 | } | 1903 | } |
1831 | } | 1904 | } |
1832 | } | 1905 | } |
1833 | } \ No newline at end of file | 1906 | } |