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 2aab4f9..8a1f267 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -127,7 +127,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
127 /// <summary>Handlers for incoming packets</summary> 127 /// <summary>Handlers for incoming packets</summary>
128 //PacketEventDictionary packetEvents = new PacketEventDictionary(); 128 //PacketEventDictionary packetEvents = new PacketEventDictionary();
129 /// <summary>Incoming packets that are awaiting handling</summary> 129 /// <summary>Incoming packets that are awaiting handling</summary>
130 private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>(); 130 //private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>();
131
132 private DoubleQueue<IncomingPacket> packetInbox = new DoubleQueue<IncomingPacket>();
131 133
132 /// <summary></summary> 134 /// <summary></summary>
133 //private UDPClientCollection m_clients = new UDPClientCollection(); 135 //private UDPClientCollection m_clients = new UDPClientCollection();
@@ -182,6 +184,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
182 /// <summary>Flag to signal when clients should send pings</summary> 184 /// <summary>Flag to signal when clients should send pings</summary>
183 protected bool m_sendPing; 185 protected bool m_sendPing;
184 186
187 private ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>();
185 private Pool<IncomingPacket> m_incomingPacketPool; 188 private Pool<IncomingPacket> m_incomingPacketPool;
186 189
187 /// <summary> 190 /// <summary>
@@ -875,6 +878,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
875 878
876 #region Queue or Send 879 #region Queue or Send
877 880
881 bool highPriority = false;
882
883 if (category != ThrottleOutPacketType.Unknown && (category & ThrottleOutPacketType.HighPriority) != 0)
884 {
885 category = (ThrottleOutPacketType)((int)category & 127);
886 highPriority = true;
887 }
888
878 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null); 889 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null);
879 // If we were not provided a method for handling unacked, use the UDPServer default method 890 // If we were not provided a method for handling unacked, use the UDPServer default method
880 outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method); 891 outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method);
@@ -883,7 +894,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
883 // continue to display the deleted object until relog. Therefore, we need to always queue a kill object 894 // continue to display the deleted object until relog. Therefore, we need to always queue a kill object
884 // packet so that it isn't sent before a queued update packet. 895 // packet so that it isn't sent before a queued update packet.
885 bool requestQueue = type == PacketType.KillObject; 896 bool requestQueue = type == PacketType.KillObject;
886 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue)) 897 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue, highPriority))
887 SendPacketFinal(outgoingPacket); 898 SendPacketFinal(outgoingPacket);
888 899
889 #endregion Queue or Send 900 #endregion Queue or Send
@@ -1168,21 +1179,46 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1168 1179
1169 #region Packet to Client Mapping 1180 #region Packet to Client Mapping
1170 1181
1171 // UseCircuitCode handling 1182 // If there is already a client for this endpoint, don't process UseCircuitCode
1172 if (packet.Type == PacketType.UseCircuitCode) 1183 IClientAPI client = null;
1184 if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
1173 { 1185 {
1174 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the 1186 // UseCircuitCode handling
1175 // buffer. 1187 if (packet.Type == PacketType.UseCircuitCode)
1176 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; 1188 {
1189 // And if there is a UseCircuitCode pending, also drop it
1190 lock (m_pendingCache)
1191 {
1192 if (m_pendingCache.Contains(endPoint))
1193 return;
1177 1194
1178 Util.FireAndForget(HandleUseCircuitCode, array); 1195 m_pendingCache.AddOrUpdate(endPoint, new Queue<UDPPacketBuffer>(), 60);
1196 }
1179 1197
1180 return; 1198 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the
1199 // buffer.
1200 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
1201
1202 Util.FireAndForget(HandleUseCircuitCode, array);
1203
1204 return;
1205 }
1206 }
1207
1208 // If this is a pending connection, enqueue, don't process yet
1209 lock (m_pendingCache)
1210 {
1211 Queue<UDPPacketBuffer> queue;
1212 if (m_pendingCache.TryGetValue(endPoint, out queue))
1213 {
1214 //m_log.DebugFormat("[LLUDPSERVER]: Enqueued a {0} packet into the pending queue", packet.Type);
1215 queue.Enqueue(buffer);
1216 return;
1217 }
1181 } 1218 }
1182 1219
1183 // Determine which agent this packet came from 1220 // Determine which agent this packet came from
1184 IClientAPI client; 1221 if (client == null || !(client is LLClientView))
1185 if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
1186 { 1222 {
1187 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); 1223 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName);
1188 return; 1224 return;
@@ -1191,7 +1227,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1191 udpClient = ((LLClientView)client).UDPClient; 1227 udpClient = ((LLClientView)client).UDPClient;
1192 1228
1193 if (!udpClient.IsConnected) 1229 if (!udpClient.IsConnected)
1230 {
1231 m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet for a unConnected client in " + m_scene.RegionInfo.RegionName);
1194 return; 1232 return;
1233 }
1195 1234
1196 #endregion Packet to Client Mapping 1235 #endregion Packet to Client Mapping
1197 1236
@@ -1321,7 +1360,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1321 incomingPacket = new IncomingPacket((LLClientView)client, packet); 1360 incomingPacket = new IncomingPacket((LLClientView)client, packet);
1322 } 1361 }
1323 1362
1324 packetInbox.Enqueue(incomingPacket); 1363 if (incomingPacket.Packet.Type == PacketType.AgentUpdate ||
1364 incomingPacket.Packet.Type == PacketType.ChatFromViewer)
1365 packetInbox.EnqueueHigh(incomingPacket);
1366 else
1367 packetInbox.EnqueueLow(incomingPacket);
1325 } 1368 }
1326 1369
1327 #region BinaryStats 1370 #region BinaryStats
@@ -1469,10 +1512,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1469 { 1512 {
1470 AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(uccp.CircuitCode.Code); 1513 AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(uccp.CircuitCode.Code);
1471 bool tp = (aCircuit.teleportFlags > 0); 1514 bool tp = (aCircuit.teleportFlags > 0);
1472 // Let's delay this for TP agents, otherwise the viewer doesn't know where to get meshes from
1473 if (!tp) 1515 if (!tp)
1474 client.SceneAgent.SendInitialDataToMe(); 1516 client.SceneAgent.SendInitialDataToMe();
1475 } 1517 }
1518
1519 // Now we know we can handle more data
1520 Thread.Sleep(200);
1521
1522 // Obtain the queue and remove it from the cache
1523 Queue<UDPPacketBuffer> queue = null;
1524
1525 lock (m_pendingCache)
1526 {
1527 if (!m_pendingCache.TryGetValue(endPoint, out queue))
1528 {
1529 m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present");
1530 return;
1531 }
1532 m_pendingCache.Remove(endPoint);
1533 }
1534
1535 m_log.DebugFormat("[LLUDPSERVER]: Client created, processing pending queue, {0} entries", queue.Count);
1536
1537 // Reinject queued packets
1538 while(queue.Count > 0)
1539 {
1540 UDPPacketBuffer buf = queue.Dequeue();
1541 PacketReceived(buf);
1542 }
1543 queue = null;
1476 } 1544 }
1477 else 1545 else
1478 { 1546 {
@@ -1480,6 +1548,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1480 m_log.WarnFormat( 1548 m_log.WarnFormat(
1481 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", 1549 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}",
1482 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint); 1550 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint);
1551 lock (m_pendingCache)
1552 m_pendingCache.Remove(endPoint);
1483 } 1553 }
1484 1554
1485 // m_log.DebugFormat( 1555 // m_log.DebugFormat(
@@ -1599,7 +1669,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1599 if (!client.SceneAgent.IsChildAgent) 1669 if (!client.SceneAgent.IsChildAgent)
1600 client.Kick("Simulator logged you out due to connection timeout"); 1670 client.Kick("Simulator logged you out due to connection timeout");
1601 1671
1602 client.CloseWithoutChecks(); 1672 client.CloseWithoutChecks(true);
1603 } 1673 }
1604 } 1674 }
1605 1675
@@ -1611,6 +1681,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1611 1681
1612 while (IsRunningInbound) 1682 while (IsRunningInbound)
1613 { 1683 {
1684 m_scene.ThreadAlive(1);
1614 try 1685 try
1615 { 1686 {
1616 IncomingPacket incomingPacket = null; 1687 IncomingPacket incomingPacket = null;
@@ -1660,6 +1731,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1660 1731
1661 while (base.IsRunningOutbound) 1732 while (base.IsRunningOutbound)
1662 { 1733 {
1734 m_scene.ThreadAlive(2);
1663 try 1735 try
1664 { 1736 {
1665 m_packetSent = false; 1737 m_packetSent = false;
@@ -1890,8 +1962,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1890 Packet packet = incomingPacket.Packet; 1962 Packet packet = incomingPacket.Packet;
1891 LLClientView client = incomingPacket.Client; 1963 LLClientView client = incomingPacket.Client;
1892 1964
1893 if (client.IsActive) 1965// if (client.IsActive)
1894 { 1966// {
1895 m_currentIncomingClient = client; 1967 m_currentIncomingClient = client;
1896 1968
1897 try 1969 try
@@ -1918,13 +1990,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1918 { 1990 {
1919 m_currentIncomingClient = null; 1991 m_currentIncomingClient = null;
1920 } 1992 }
1921 } 1993// }
1922 else 1994// else
1923 { 1995// {
1924 m_log.DebugFormat( 1996// m_log.DebugFormat(
1925 "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", 1997// "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}",
1926 packet.Type, client.Name, m_scene.RegionInfo.RegionName); 1998// packet.Type, client.Name, m_scene.RegionInfo.RegionName);
1927 } 1999// }
1928 2000
1929 IncomingPacketsProcessed++; 2001 IncomingPacketsProcessed++;
1930 } 2002 }
@@ -1936,8 +2008,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1936 if (!client.IsLoggingOut) 2008 if (!client.IsLoggingOut)
1937 { 2009 {
1938 client.IsLoggingOut = true; 2010 client.IsLoggingOut = true;
1939 client.Close(); 2011 client.Close(false, false);
1940 } 2012 }
1941 } 2013 }
1942 } 2014 }
1943} \ No newline at end of file 2015}