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 8d957dc..01981dd 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(
@@ -1904,6 +1976,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1904 1976
1905 while (IsRunningInbound) 1977 while (IsRunningInbound)
1906 { 1978 {
1979 m_scene.ThreadAlive(1);
1907 try 1980 try
1908 { 1981 {
1909 IncomingPacket incomingPacket = null; 1982 IncomingPacket incomingPacket = null;
@@ -1953,6 +2026,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1953 2026
1954 while (base.IsRunningOutbound) 2027 while (base.IsRunningOutbound)
1955 { 2028 {
2029 m_scene.ThreadAlive(2);
1956 try 2030 try
1957 { 2031 {
1958 m_packetSent = false; 2032 m_packetSent = false;
@@ -2188,8 +2262,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2188 Packet packet = incomingPacket.Packet; 2262 Packet packet = incomingPacket.Packet;
2189 LLClientView client = incomingPacket.Client; 2263 LLClientView client = incomingPacket.Client;
2190 2264
2191 if (client.IsActive) 2265// if (client.IsActive)
2192 { 2266// {
2193 m_currentIncomingClient = client; 2267 m_currentIncomingClient = client;
2194 2268
2195 try 2269 try
@@ -2216,13 +2290,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2216 { 2290 {
2217 m_currentIncomingClient = null; 2291 m_currentIncomingClient = null;
2218 } 2292 }
2219 } 2293// }
2220 else 2294// else
2221 { 2295// {
2222 m_log.DebugFormat( 2296// m_log.DebugFormat(
2223 "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", 2297// "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}",
2224 packet.Type, client.Name, m_scene.RegionInfo.RegionName); 2298// packet.Type, client.Name, m_scene.RegionInfo.RegionName);
2225 } 2299// }
2226 2300
2227 IncomingPacketsProcessed++; 2301 IncomingPacketsProcessed++;
2228 } 2302 }
@@ -2238,4 +2312,4 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2238 } 2312 }
2239 } 2313 }
2240 } 2314 }
2241} \ No newline at end of file 2315}