aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs134
1 files changed, 104 insertions, 30 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 102e581..ad3f715 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -210,7 +210,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
210 /// <summary>Handlers for incoming packets</summary> 210 /// <summary>Handlers for incoming packets</summary>
211 //PacketEventDictionary packetEvents = new PacketEventDictionary(); 211 //PacketEventDictionary packetEvents = new PacketEventDictionary();
212 /// <summary>Incoming packets that are awaiting handling</summary> 212 /// <summary>Incoming packets that are awaiting handling</summary>
213 private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>(); 213 //private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>();
214
215 private DoubleQueue<IncomingPacket> packetInbox = new DoubleQueue<IncomingPacket>();
214 216
215 /// <summary></summary> 217 /// <summary></summary>
216 //private UDPClientCollection m_clients = new UDPClientCollection(); 218 //private UDPClientCollection m_clients = new UDPClientCollection();
@@ -265,6 +267,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
265 /// <summary>Flag to signal when clients should send pings</summary> 267 /// <summary>Flag to signal when clients should send pings</summary>
266 protected bool m_sendPing; 268 protected bool m_sendPing;
267 269
270 private ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>();
271
268 /// <summary> 272 /// <summary>
269 /// Event used to signal when queued packets are available for sending. 273 /// Event used to signal when queued packets are available for sending.
270 /// </summary> 274 /// </summary>
@@ -1011,6 +1015,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1011 1015
1012 #region Queue or Send 1016 #region Queue or Send
1013 1017
1018 bool highPriority = false;
1019
1020 if (category != ThrottleOutPacketType.Unknown && (category & ThrottleOutPacketType.HighPriority) != 0)
1021 {
1022 category = (ThrottleOutPacketType)((int)category & 127);
1023 highPriority = true;
1024 }
1025
1014 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null); 1026 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null);
1015 // If we were not provided a method for handling unacked, use the UDPServer default method 1027 // If we were not provided a method for handling unacked, use the UDPServer default method
1016 outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method); 1028 outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method);
@@ -1019,7 +1031,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1019 // continue to display the deleted object until relog. Therefore, we need to always queue a kill object 1031 // continue to display the deleted object until relog. Therefore, we need to always queue a kill object
1020 // packet so that it isn't sent before a queued update packet. 1032 // packet so that it isn't sent before a queued update packet.
1021 bool requestQueue = type == PacketType.KillObject; 1033 bool requestQueue = type == PacketType.KillObject;
1022 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue)) 1034 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue, highPriority))
1023 SendPacketFinal(outgoingPacket); 1035 SendPacketFinal(outgoingPacket);
1024 1036
1025 #endregion Queue or Send 1037 #endregion Queue or Send
@@ -1310,34 +1322,59 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1310 1322
1311 #region Packet to Client Mapping 1323 #region Packet to Client Mapping
1312 1324
1313 // UseCircuitCode handling 1325 // If there is already a client for this endpoint, don't process UseCircuitCode
1314 if (packet.Type == PacketType.UseCircuitCode) 1326 IClientAPI client = null;
1327 if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
1315 { 1328 {
1316 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the 1329 // UseCircuitCode handling
1317 // buffer. 1330 if (packet.Type == PacketType.UseCircuitCode)
1318 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; 1331 {
1332 // And if there is a UseCircuitCode pending, also drop it
1333 lock (m_pendingCache)
1334 {
1335 if (m_pendingCache.Contains(endPoint))
1336 return;
1319 1337
1320 Util.FireAndForget(HandleUseCircuitCode, array); 1338 m_pendingCache.AddOrUpdate(endPoint, new Queue<UDPPacketBuffer>(), 60);
1339 }
1321 1340
1322 return; 1341 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the
1342 // buffer.
1343 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
1344
1345 Util.FireAndForget(HandleUseCircuitCode, array);
1346
1347 return;
1348 }
1323 } 1349 }
1324 else if (packet.Type == PacketType.CompleteAgentMovement) 1350
1351 // If this is a pending connection, enqueue, don't process yet
1352 lock (m_pendingCache)
1325 { 1353 {
1326 // Send ack straight away to let the viewer know that we got it. 1354 Queue<UDPPacketBuffer> queue;
1327 SendAckImmediate(endPoint, packet.Header.Sequence); 1355 if (m_pendingCache.TryGetValue(endPoint, out queue))
1356 {
1357 //m_log.DebugFormat("[LLUDPSERVER]: Enqueued a {0} packet into the pending queue", packet.Type);
1358 queue.Enqueue(buffer);
1359 return;
1360 }
1361 else if (packet.Type == PacketType.CompleteAgentMovement)
1362 {
1363 // Send ack straight away to let the viewer know that we got it.
1364 SendAckImmediate(endPoint, packet.Header.Sequence);
1328 1365
1329 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the 1366 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the
1330 // buffer. 1367 // buffer.
1331 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; 1368 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
1332 1369
1333 Util.FireAndForget(HandleCompleteMovementIntoRegion, array); 1370 Util.FireAndForget(HandleCompleteMovementIntoRegion, array);
1334 1371
1335 return; 1372 return;
1373 }
1336 } 1374 }
1337 1375
1338 // Determine which agent this packet came from 1376 // Determine which agent this packet came from
1339 IClientAPI client; 1377 if (client == null || !(client is LLClientView))
1340 if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
1341 { 1378 {
1342 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); 1379 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName);
1343 1380
@@ -1354,7 +1391,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1354 udpClient = ((LLClientView)client).UDPClient; 1391 udpClient = ((LLClientView)client).UDPClient;
1355 1392
1356 if (!udpClient.IsConnected) 1393 if (!udpClient.IsConnected)
1394 {
1395 m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet for a unConnected client in " + m_scene.RegionInfo.RegionName);
1357 return; 1396 return;
1397 }
1358 1398
1359 #endregion Packet to Client Mapping 1399 #endregion Packet to Client Mapping
1360 1400
@@ -1503,7 +1543,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1503 incomingPacket = new IncomingPacket((LLClientView)client, packet); 1543 incomingPacket = new IncomingPacket((LLClientView)client, packet);
1504 } 1544 }
1505 1545
1506 packetInbox.Enqueue(incomingPacket); 1546 if (incomingPacket.Packet.Type == PacketType.AgentUpdate ||
1547 incomingPacket.Packet.Type == PacketType.ChatFromViewer)
1548 packetInbox.EnqueueHigh(incomingPacket);
1549 else
1550 packetInbox.EnqueueLow(incomingPacket);
1507 } 1551 }
1508 1552
1509 #region BinaryStats 1553 #region BinaryStats
@@ -1655,6 +1699,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1655 if (!tp) 1699 if (!tp)
1656 client.SceneAgent.SendInitialDataToMe(); 1700 client.SceneAgent.SendInitialDataToMe();
1657 } 1701 }
1702
1703 // Now we know we can handle more data
1704 Thread.Sleep(200);
1705
1706 // Obtain the queue and remove it from the cache
1707 Queue<UDPPacketBuffer> queue = null;
1708
1709 lock (m_pendingCache)
1710 {
1711 if (!m_pendingCache.TryGetValue(endPoint, out queue))
1712 {
1713 m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present");
1714 return;
1715 }
1716 m_pendingCache.Remove(endPoint);
1717 }
1718
1719 m_log.DebugFormat("[LLUDPSERVER]: Client created, processing pending queue, {0} entries", queue.Count);
1720
1721 // Reinject queued packets
1722 while(queue.Count > 0)
1723 {
1724 UDPPacketBuffer buf = queue.Dequeue();
1725 PacketReceived(buf);
1726 }
1727 queue = null;
1658 } 1728 }
1659 else 1729 else
1660 { 1730 {
@@ -1662,6 +1732,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1662 m_log.WarnFormat( 1732 m_log.WarnFormat(
1663 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", 1733 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}",
1664 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint); 1734 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint);
1735 lock (m_pendingCache)
1736 m_pendingCache.Remove(endPoint);
1665 } 1737 }
1666 1738
1667 // m_log.DebugFormat( 1739 // m_log.DebugFormat(
@@ -1860,6 +1932,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1860 1932
1861 while (IsRunningInbound) 1933 while (IsRunningInbound)
1862 { 1934 {
1935 m_scene.ThreadAlive(1);
1863 try 1936 try
1864 { 1937 {
1865 IncomingPacket incomingPacket = null; 1938 IncomingPacket incomingPacket = null;
@@ -1909,6 +1982,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1909 1982
1910 while (base.IsRunningOutbound) 1983 while (base.IsRunningOutbound)
1911 { 1984 {
1985 m_scene.ThreadAlive(2);
1912 try 1986 try
1913 { 1987 {
1914 m_packetSent = false; 1988 m_packetSent = false;
@@ -2144,8 +2218,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2144 Packet packet = incomingPacket.Packet; 2218 Packet packet = incomingPacket.Packet;
2145 LLClientView client = incomingPacket.Client; 2219 LLClientView client = incomingPacket.Client;
2146 2220
2147 if (client.IsActive) 2221// if (client.IsActive)
2148 { 2222// {
2149 m_currentIncomingClient = client; 2223 m_currentIncomingClient = client;
2150 2224
2151 try 2225 try
@@ -2172,13 +2246,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2172 { 2246 {
2173 m_currentIncomingClient = null; 2247 m_currentIncomingClient = null;
2174 } 2248 }
2175 } 2249// }
2176 else 2250// else
2177 { 2251// {
2178 m_log.DebugFormat( 2252// m_log.DebugFormat(
2179 "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", 2253// "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}",
2180 packet.Type, client.Name, m_scene.RegionInfo.RegionName); 2254// packet.Type, client.Name, m_scene.RegionInfo.RegionName);
2181 } 2255// }
2182 2256
2183 IncomingPacketsProcessed++; 2257 IncomingPacketsProcessed++;
2184 } 2258 }
@@ -2194,4 +2268,4 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2194 } 2268 }
2195 } 2269 }
2196 } 2270 }
2197} \ No newline at end of file 2271}