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.cs138
1 files changed, 106 insertions, 32 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 85fe1a4..2a2c819 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -184,7 +184,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
184 /// <summary>Handlers for incoming packets</summary> 184 /// <summary>Handlers for incoming packets</summary>
185 //PacketEventDictionary packetEvents = new PacketEventDictionary(); 185 //PacketEventDictionary packetEvents = new PacketEventDictionary();
186 /// <summary>Incoming packets that are awaiting handling</summary> 186 /// <summary>Incoming packets that are awaiting handling</summary>
187 private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>(); 187 //private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>();
188
189 private DoubleQueue<IncomingPacket> packetInbox = new DoubleQueue<IncomingPacket>();
188 190
189 /// <summary></summary> 191 /// <summary></summary>
190 //private UDPClientCollection m_clients = new UDPClientCollection(); 192 //private UDPClientCollection m_clients = new UDPClientCollection();
@@ -239,6 +241,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
239 /// <summary>Flag to signal when clients should send pings</summary> 241 /// <summary>Flag to signal when clients should send pings</summary>
240 protected bool m_sendPing; 242 protected bool m_sendPing;
241 243
244 private ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>();
245
242 /// <summary> 246 /// <summary>
243 /// Event used to signal when queued packets are available for sending. 247 /// Event used to signal when queued packets are available for sending.
244 /// </summary> 248 /// </summary>
@@ -977,6 +981,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
977 981
978 #region Queue or Send 982 #region Queue or Send
979 983
984 bool highPriority = false;
985
986 if (category != ThrottleOutPacketType.Unknown && (category & ThrottleOutPacketType.HighPriority) != 0)
987 {
988 category = (ThrottleOutPacketType)((int)category & 127);
989 highPriority = true;
990 }
991
980 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null); 992 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null);
981 // If we were not provided a method for handling unacked, use the UDPServer default method 993 // If we were not provided a method for handling unacked, use the UDPServer default method
982 outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method); 994 outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method);
@@ -985,7 +997,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
985 // continue to display the deleted object until relog. Therefore, we need to always queue a kill object 997 // continue to display the deleted object until relog. Therefore, we need to always queue a kill object
986 // packet so that it isn't sent before a queued update packet. 998 // packet so that it isn't sent before a queued update packet.
987 bool requestQueue = type == PacketType.KillObject; 999 bool requestQueue = type == PacketType.KillObject;
988 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue)) 1000 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue, highPriority))
989 SendPacketFinal(outgoingPacket); 1001 SendPacketFinal(outgoingPacket);
990 1002
991 #endregion Queue or Send 1003 #endregion Queue or Send
@@ -1270,34 +1282,59 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1270 1282
1271 #region Packet to Client Mapping 1283 #region Packet to Client Mapping
1272 1284
1273 // UseCircuitCode handling 1285 // If there is already a client for this endpoint, don't process UseCircuitCode
1274 if (packet.Type == PacketType.UseCircuitCode) 1286 IClientAPI client = null;
1287 if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
1275 { 1288 {
1276 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the 1289 // UseCircuitCode handling
1277 // buffer. 1290 if (packet.Type == PacketType.UseCircuitCode)
1278 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; 1291 {
1292 // And if there is a UseCircuitCode pending, also drop it
1293 lock (m_pendingCache)
1294 {
1295 if (m_pendingCache.Contains(endPoint))
1296 return;
1279 1297
1280 Util.FireAndForget(HandleUseCircuitCode, array); 1298 m_pendingCache.AddOrUpdate(endPoint, new Queue<UDPPacketBuffer>(), 60);
1299 }
1281 1300
1282 return; 1301 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the
1302 // buffer.
1303 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
1304
1305 Util.FireAndForget(HandleUseCircuitCode, array);
1306
1307 return;
1308 }
1283 } 1309 }
1284 else if (packet.Type == PacketType.CompleteAgentMovement) 1310
1311 // If this is a pending connection, enqueue, don't process yet
1312 lock (m_pendingCache)
1285 { 1313 {
1286 // Send ack straight away to let the viewer know that we got it. 1314 Queue<UDPPacketBuffer> queue;
1287 SendAckImmediate(endPoint, packet.Header.Sequence); 1315 if (m_pendingCache.TryGetValue(endPoint, out queue))
1316 {
1317 //m_log.DebugFormat("[LLUDPSERVER]: Enqueued a {0} packet into the pending queue", packet.Type);
1318 queue.Enqueue(buffer);
1319 return;
1320 }
1321 else if (packet.Type == PacketType.CompleteAgentMovement)
1322 {
1323 // Send ack straight away to let the viewer know that we got it.
1324 SendAckImmediate(endPoint, packet.Header.Sequence);
1288 1325
1289 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the 1326 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the
1290 // buffer. 1327 // buffer.
1291 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; 1328 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
1292 1329
1293 Util.FireAndForget(HandleCompleteMovementIntoRegion, array); 1330 Util.FireAndForget(HandleCompleteMovementIntoRegion, array);
1294 1331
1295 return; 1332 return;
1333 }
1296 } 1334 }
1297 1335
1298 // Determine which agent this packet came from 1336 // Determine which agent this packet came from
1299 IClientAPI client; 1337 if (client == null || !(client is LLClientView))
1300 if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
1301 { 1338 {
1302 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); 1339 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName);
1303 return; 1340 return;
@@ -1306,7 +1343,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1306 udpClient = ((LLClientView)client).UDPClient; 1343 udpClient = ((LLClientView)client).UDPClient;
1307 1344
1308 if (!udpClient.IsConnected) 1345 if (!udpClient.IsConnected)
1346 {
1347 m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet for a unConnected client in " + m_scene.RegionInfo.RegionName);
1309 return; 1348 return;
1349 }
1310 1350
1311 #endregion Packet to Client Mapping 1351 #endregion Packet to Client Mapping
1312 1352
@@ -1455,7 +1495,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1455 incomingPacket = new IncomingPacket((LLClientView)client, packet); 1495 incomingPacket = new IncomingPacket((LLClientView)client, packet);
1456 } 1496 }
1457 1497
1458 packetInbox.Enqueue(incomingPacket); 1498 if (incomingPacket.Packet.Type == PacketType.AgentUpdate ||
1499 incomingPacket.Packet.Type == PacketType.ChatFromViewer)
1500 packetInbox.EnqueueHigh(incomingPacket);
1501 else
1502 packetInbox.EnqueueLow(incomingPacket);
1459 } 1503 }
1460 1504
1461 #region BinaryStats 1505 #region BinaryStats
@@ -1607,6 +1651,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1607 if (!tp) 1651 if (!tp)
1608 client.SceneAgent.SendInitialDataToMe(); 1652 client.SceneAgent.SendInitialDataToMe();
1609 } 1653 }
1654
1655 // Now we know we can handle more data
1656 Thread.Sleep(200);
1657
1658 // Obtain the queue and remove it from the cache
1659 Queue<UDPPacketBuffer> queue = null;
1660
1661 lock (m_pendingCache)
1662 {
1663 if (!m_pendingCache.TryGetValue(endPoint, out queue))
1664 {
1665 m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present");
1666 return;
1667 }
1668 m_pendingCache.Remove(endPoint);
1669 }
1670
1671 m_log.DebugFormat("[LLUDPSERVER]: Client created, processing pending queue, {0} entries", queue.Count);
1672
1673 // Reinject queued packets
1674 while(queue.Count > 0)
1675 {
1676 UDPPacketBuffer buf = queue.Dequeue();
1677 PacketReceived(buf);
1678 }
1679 queue = null;
1610 } 1680 }
1611 else 1681 else
1612 { 1682 {
@@ -1614,6 +1684,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1614 m_log.WarnFormat( 1684 m_log.WarnFormat(
1615 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", 1685 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}",
1616 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint); 1686 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint);
1687 lock (m_pendingCache)
1688 m_pendingCache.Remove(endPoint);
1617 } 1689 }
1618 1690
1619 // m_log.DebugFormat( 1691 // m_log.DebugFormat(
@@ -1800,7 +1872,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1800 if (!client.SceneAgent.IsChildAgent) 1872 if (!client.SceneAgent.IsChildAgent)
1801 client.Kick("Simulator logged you out due to connection timeout."); 1873 client.Kick("Simulator logged you out due to connection timeout.");
1802 1874
1803 client.CloseWithoutChecks(); 1875 client.CloseWithoutChecks(true);
1804 } 1876 }
1805 } 1877 }
1806 1878
@@ -1812,6 +1884,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1812 1884
1813 while (IsRunningInbound) 1885 while (IsRunningInbound)
1814 { 1886 {
1887 m_scene.ThreadAlive(1);
1815 try 1888 try
1816 { 1889 {
1817 IncomingPacket incomingPacket = null; 1890 IncomingPacket incomingPacket = null;
@@ -1861,6 +1934,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1861 1934
1862 while (base.IsRunningOutbound) 1935 while (base.IsRunningOutbound)
1863 { 1936 {
1937 m_scene.ThreadAlive(2);
1864 try 1938 try
1865 { 1939 {
1866 m_packetSent = false; 1940 m_packetSent = false;
@@ -2095,8 +2169,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2095 Packet packet = incomingPacket.Packet; 2169 Packet packet = incomingPacket.Packet;
2096 LLClientView client = incomingPacket.Client; 2170 LLClientView client = incomingPacket.Client;
2097 2171
2098 if (client.IsActive) 2172// if (client.IsActive)
2099 { 2173// {
2100 m_currentIncomingClient = client; 2174 m_currentIncomingClient = client;
2101 2175
2102 try 2176 try
@@ -2123,13 +2197,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2123 { 2197 {
2124 m_currentIncomingClient = null; 2198 m_currentIncomingClient = null;
2125 } 2199 }
2126 } 2200// }
2127 else 2201// else
2128 { 2202// {
2129 m_log.DebugFormat( 2203// m_log.DebugFormat(
2130 "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", 2204// "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}",
2131 packet.Type, client.Name, m_scene.RegionInfo.RegionName); 2205// packet.Type, client.Name, m_scene.RegionInfo.RegionName);
2132 } 2206// }
2133 2207
2134 IncomingPacketsProcessed++; 2208 IncomingPacketsProcessed++;
2135 } 2209 }
@@ -2141,8 +2215,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2141 if (!client.IsLoggingOut) 2215 if (!client.IsLoggingOut)
2142 { 2216 {
2143 client.IsLoggingOut = true; 2217 client.IsLoggingOut = true;
2144 client.Close(); 2218 client.Close(false, false);
2145 } 2219 }
2146 } 2220 }
2147 } 2221 }
2148} \ No newline at end of file 2222}