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.cs122
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}