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, 97 insertions, 25 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 8eb2e06..fab66ce 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
@@ -1376,10 +1419,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1376 { 1419 {
1377 AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(uccp.CircuitCode.Code); 1420 AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(uccp.CircuitCode.Code);
1378 bool tp = (aCircuit.teleportFlags > 0); 1421 bool tp = (aCircuit.teleportFlags > 0);
1379 // Let's delay this for TP agents, otherwise the viewer doesn't know where to get meshes from
1380 if (!tp) 1422 if (!tp)
1381 client.SceneAgent.SendInitialDataToMe(); 1423 client.SceneAgent.SendInitialDataToMe();
1382 } 1424 }
1425
1426 // Now we know we can handle more data
1427 Thread.Sleep(200);
1428
1429 // Obtain the queue and remove it from the cache
1430 Queue<UDPPacketBuffer> queue = null;
1431
1432 lock (m_pendingCache)
1433 {
1434 if (!m_pendingCache.TryGetValue(endPoint, out queue))
1435 {
1436 m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present");
1437 return;
1438 }
1439 m_pendingCache.Remove(endPoint);
1440 }
1441
1442 m_log.DebugFormat("[LLUDPSERVER]: Client created, processing pending queue, {0} entries", queue.Count);
1443
1444 // Reinject queued packets
1445 while(queue.Count > 0)
1446 {
1447 UDPPacketBuffer buf = queue.Dequeue();
1448 PacketReceived(buf);
1449 }
1450 queue = null;
1383 } 1451 }
1384 else 1452 else
1385 { 1453 {
@@ -1387,6 +1455,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1387 m_log.WarnFormat( 1455 m_log.WarnFormat(
1388 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", 1456 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}",
1389 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint); 1457 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint);
1458 lock (m_pendingCache)
1459 m_pendingCache.Remove(endPoint);
1390 } 1460 }
1391 1461
1392 // m_log.DebugFormat( 1462 // m_log.DebugFormat(
@@ -1505,7 +1575,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1505 if (!client.SceneAgent.IsChildAgent) 1575 if (!client.SceneAgent.IsChildAgent)
1506 client.Kick("Simulator logged you out due to connection timeout"); 1576 client.Kick("Simulator logged you out due to connection timeout");
1507 1577
1508 client.CloseWithoutChecks(); 1578 client.CloseWithoutChecks(true);
1509 } 1579 }
1510 } 1580 }
1511 1581
@@ -1517,6 +1587,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1517 1587
1518 while (IsRunningInbound) 1588 while (IsRunningInbound)
1519 { 1589 {
1590 m_scene.ThreadAlive(1);
1520 try 1591 try
1521 { 1592 {
1522 IncomingPacket incomingPacket = null; 1593 IncomingPacket incomingPacket = null;
@@ -1564,6 +1635,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1564 1635
1565 while (base.IsRunningOutbound) 1636 while (base.IsRunningOutbound)
1566 { 1637 {
1638 m_scene.ThreadAlive(2);
1567 try 1639 try
1568 { 1640 {
1569 m_packetSent = false; 1641 m_packetSent = false;
@@ -1794,8 +1866,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1794 Packet packet = incomingPacket.Packet; 1866 Packet packet = incomingPacket.Packet;
1795 LLClientView client = incomingPacket.Client; 1867 LLClientView client = incomingPacket.Client;
1796 1868
1797 if (client.IsActive) 1869// if (client.IsActive)
1798 { 1870// {
1799 m_currentIncomingClient = client; 1871 m_currentIncomingClient = client;
1800 1872
1801 try 1873 try
@@ -1822,13 +1894,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1822 { 1894 {
1823 m_currentIncomingClient = null; 1895 m_currentIncomingClient = null;
1824 } 1896 }
1825 } 1897// }
1826 else 1898// else
1827 { 1899// {
1828 m_log.DebugFormat( 1900// m_log.DebugFormat(
1829 "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", 1901// "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}",
1830 packet.Type, client.Name, m_scene.RegionInfo.RegionName); 1902// packet.Type, client.Name, m_scene.RegionInfo.RegionName);
1831 } 1903// }
1832 1904
1833 IncomingPacketsProcessed++; 1905 IncomingPacketsProcessed++;
1834 } 1906 }
@@ -1840,8 +1912,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1840 if (!client.IsLoggingOut) 1912 if (!client.IsLoggingOut)
1841 { 1913 {
1842 client.IsLoggingOut = true; 1914 client.IsLoggingOut = true;
1843 client.Close(); 1915 client.Close(false, false);
1844 } 1916 }
1845 } 1917 }
1846 } 1918 }
1847} \ No newline at end of file 1919}