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.cs121
1 files changed, 97 insertions, 24 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 85270a6..77b07ed 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
@@ -1473,6 +1516,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1473 if (!tp) 1516 if (!tp)
1474 client.SceneAgent.SendInitialDataToMe(); 1517 client.SceneAgent.SendInitialDataToMe();
1475 } 1518 }
1519
1520 // Now we know we can handle more data
1521 Thread.Sleep(200);
1522
1523 // Obtain the queue and remove it from the cache
1524 Queue<UDPPacketBuffer> queue = null;
1525
1526 lock (m_pendingCache)
1527 {
1528 if (!m_pendingCache.TryGetValue(endPoint, out queue))
1529 {
1530 m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present");
1531 return;
1532 }
1533 m_pendingCache.Remove(endPoint);
1534 }
1535
1536 m_log.DebugFormat("[LLUDPSERVER]: Client created, processing pending queue, {0} entries", queue.Count);
1537
1538 // Reinject queued packets
1539 while(queue.Count > 0)
1540 {
1541 UDPPacketBuffer buf = queue.Dequeue();
1542 PacketReceived(buf);
1543 }
1544 queue = null;
1476 } 1545 }
1477 else 1546 else
1478 { 1547 {
@@ -1480,6 +1549,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1480 m_log.WarnFormat( 1549 m_log.WarnFormat(
1481 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", 1550 "[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); 1551 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint);
1552 lock (m_pendingCache)
1553 m_pendingCache.Remove(endPoint);
1483 } 1554 }
1484 1555
1485 // m_log.DebugFormat( 1556 // m_log.DebugFormat(
@@ -1599,7 +1670,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1599 if (!client.SceneAgent.IsChildAgent) 1670 if (!client.SceneAgent.IsChildAgent)
1600 client.Kick("Simulator logged you out due to connection timeout"); 1671 client.Kick("Simulator logged you out due to connection timeout");
1601 1672
1602 client.CloseWithoutChecks(); 1673 client.CloseWithoutChecks(true);
1603 } 1674 }
1604 } 1675 }
1605 1676
@@ -1611,6 +1682,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1611 1682
1612 while (IsRunningInbound) 1683 while (IsRunningInbound)
1613 { 1684 {
1685 m_scene.ThreadAlive(1);
1614 try 1686 try
1615 { 1687 {
1616 IncomingPacket incomingPacket = null; 1688 IncomingPacket incomingPacket = null;
@@ -1660,6 +1732,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1660 1732
1661 while (base.IsRunningOutbound) 1733 while (base.IsRunningOutbound)
1662 { 1734 {
1735 m_scene.ThreadAlive(2);
1663 try 1736 try
1664 { 1737 {
1665 m_packetSent = false; 1738 m_packetSent = false;
@@ -1890,8 +1963,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1890 Packet packet = incomingPacket.Packet; 1963 Packet packet = incomingPacket.Packet;
1891 LLClientView client = incomingPacket.Client; 1964 LLClientView client = incomingPacket.Client;
1892 1965
1893 if (client.IsActive) 1966// if (client.IsActive)
1894 { 1967// {
1895 m_currentIncomingClient = client; 1968 m_currentIncomingClient = client;
1896 1969
1897 try 1970 try
@@ -1918,13 +1991,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1918 { 1991 {
1919 m_currentIncomingClient = null; 1992 m_currentIncomingClient = null;
1920 } 1993 }
1921 } 1994// }
1922 else 1995// else
1923 { 1996// {
1924 m_log.DebugFormat( 1997// m_log.DebugFormat(
1925 "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", 1998// "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}",
1926 packet.Type, client.Name, m_scene.RegionInfo.RegionName); 1999// packet.Type, client.Name, m_scene.RegionInfo.RegionName);
1927 } 2000// }
1928 2001
1929 IncomingPacketsProcessed++; 2002 IncomingPacketsProcessed++;
1930 } 2003 }
@@ -1936,8 +2009,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1936 if (!client.IsLoggingOut) 2009 if (!client.IsLoggingOut)
1937 { 2010 {
1938 client.IsLoggingOut = true; 2011 client.IsLoggingOut = true;
1939 client.Close(); 2012 client.Close(false, false);
1940 } 2013 }
1941 } 2014 }
1942 } 2015 }
1943} \ No newline at end of file 2016}