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 72516cd..4154ef2 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -126,7 +126,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
126 /// <summary>Handlers for incoming packets</summary> 126 /// <summary>Handlers for incoming packets</summary>
127 //PacketEventDictionary packetEvents = new PacketEventDictionary(); 127 //PacketEventDictionary packetEvents = new PacketEventDictionary();
128 /// <summary>Incoming packets that are awaiting handling</summary> 128 /// <summary>Incoming packets that are awaiting handling</summary>
129 private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>(); 129 //private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>();
130
131 private DoubleQueue<IncomingPacket> packetInbox = new DoubleQueue<IncomingPacket>();
130 132
131 /// <summary></summary> 133 /// <summary></summary>
132 //private UDPClientCollection m_clients = new UDPClientCollection(); 134 //private UDPClientCollection m_clients = new UDPClientCollection();
@@ -181,6 +183,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
181 /// <summary>Flag to signal when clients should send pings</summary> 183 /// <summary>Flag to signal when clients should send pings</summary>
182 protected bool m_sendPing; 184 protected bool m_sendPing;
183 185
186 private ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>();
184 private Pool<IncomingPacket> m_incomingPacketPool; 187 private Pool<IncomingPacket> m_incomingPacketPool;
185 188
186 /// <summary> 189 /// <summary>
@@ -787,6 +790,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
787 790
788 #region Queue or Send 791 #region Queue or Send
789 792
793 bool highPriority = false;
794
795 if (category != ThrottleOutPacketType.Unknown && (category & ThrottleOutPacketType.HighPriority) != 0)
796 {
797 category = (ThrottleOutPacketType)((int)category & 127);
798 highPriority = true;
799 }
800
790 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null); 801 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null);
791 // If we were not provided a method for handling unacked, use the UDPServer default method 802 // If we were not provided a method for handling unacked, use the UDPServer default method
792 outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method); 803 outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method);
@@ -795,7 +806,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
795 // continue to display the deleted object until relog. Therefore, we need to always queue a kill object 806 // continue to display the deleted object until relog. Therefore, we need to always queue a kill object
796 // packet so that it isn't sent before a queued update packet. 807 // packet so that it isn't sent before a queued update packet.
797 bool requestQueue = type == PacketType.KillObject; 808 bool requestQueue = type == PacketType.KillObject;
798 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue)) 809 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue, highPriority))
799 SendPacketFinal(outgoingPacket); 810 SendPacketFinal(outgoingPacket);
800 811
801 #endregion Queue or Send 812 #endregion Queue or Send
@@ -1080,21 +1091,46 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1080 1091
1081 #region Packet to Client Mapping 1092 #region Packet to Client Mapping
1082 1093
1083 // UseCircuitCode handling 1094 // If there is already a client for this endpoint, don't process UseCircuitCode
1084 if (packet.Type == PacketType.UseCircuitCode) 1095 IClientAPI client = null;
1096 if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
1085 { 1097 {
1086 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the 1098 // UseCircuitCode handling
1087 // buffer. 1099 if (packet.Type == PacketType.UseCircuitCode)
1088 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; 1100 {
1101 // And if there is a UseCircuitCode pending, also drop it
1102 lock (m_pendingCache)
1103 {
1104 if (m_pendingCache.Contains(endPoint))
1105 return;
1089 1106
1090 Util.FireAndForget(HandleUseCircuitCode, array); 1107 m_pendingCache.AddOrUpdate(endPoint, new Queue<UDPPacketBuffer>(), 60);
1108 }
1091 1109
1092 return; 1110 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the
1111 // buffer.
1112 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
1113
1114 Util.FireAndForget(HandleUseCircuitCode, array);
1115
1116 return;
1117 }
1118 }
1119
1120 // If this is a pending connection, enqueue, don't process yet
1121 lock (m_pendingCache)
1122 {
1123 Queue<UDPPacketBuffer> queue;
1124 if (m_pendingCache.TryGetValue(endPoint, out queue))
1125 {
1126 //m_log.DebugFormat("[LLUDPSERVER]: Enqueued a {0} packet into the pending queue", packet.Type);
1127 queue.Enqueue(buffer);
1128 return;
1129 }
1093 } 1130 }
1094 1131
1095 // Determine which agent this packet came from 1132 // Determine which agent this packet came from
1096 IClientAPI client; 1133 if (client == null || !(client is LLClientView))
1097 if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
1098 { 1134 {
1099 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); 1135 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName);
1100 return; 1136 return;
@@ -1103,7 +1139,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1103 udpClient = ((LLClientView)client).UDPClient; 1139 udpClient = ((LLClientView)client).UDPClient;
1104 1140
1105 if (!udpClient.IsConnected) 1141 if (!udpClient.IsConnected)
1142 {
1143 m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet for a unConnected client in " + m_scene.RegionInfo.RegionName);
1106 return; 1144 return;
1145 }
1107 1146
1108 #endregion Packet to Client Mapping 1147 #endregion Packet to Client Mapping
1109 1148
@@ -1233,7 +1272,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1233 incomingPacket = new IncomingPacket((LLClientView)client, packet); 1272 incomingPacket = new IncomingPacket((LLClientView)client, packet);
1234 } 1273 }
1235 1274
1236 packetInbox.Enqueue(incomingPacket); 1275 if (incomingPacket.Packet.Type == PacketType.AgentUpdate ||
1276 incomingPacket.Packet.Type == PacketType.ChatFromViewer)
1277 packetInbox.EnqueueHigh(incomingPacket);
1278 else
1279 packetInbox.EnqueueLow(incomingPacket);
1237 } 1280 }
1238 1281
1239 #region BinaryStats 1282 #region BinaryStats
@@ -1379,6 +1422,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1379 // We only want to send initial data to new clients, not ones which are being converted from child to root. 1422 // We only want to send initial data to new clients, not ones which are being converted from child to root.
1380 if (client != null) 1423 if (client != null)
1381 client.SceneAgent.SendInitialDataToMe(); 1424 client.SceneAgent.SendInitialDataToMe();
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;
1382 } 1451 }
1383 else 1452 else
1384 { 1453 {
@@ -1386,6 +1455,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1386 m_log.WarnFormat( 1455 m_log.WarnFormat(
1387 "[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}",
1388 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);
1389 } 1460 }
1390 1461
1391 // m_log.DebugFormat( 1462 // m_log.DebugFormat(
@@ -1504,7 +1575,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1504 if (!client.SceneAgent.IsChildAgent) 1575 if (!client.SceneAgent.IsChildAgent)
1505 client.Kick("Simulator logged you out due to connection timeout"); 1576 client.Kick("Simulator logged you out due to connection timeout");
1506 1577
1507 client.CloseWithoutChecks(); 1578 client.CloseWithoutChecks(true);
1508 } 1579 }
1509 } 1580 }
1510 1581
@@ -1516,6 +1587,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1516 1587
1517 while (IsRunningInbound) 1588 while (IsRunningInbound)
1518 { 1589 {
1590 m_scene.ThreadAlive(1);
1519 try 1591 try
1520 { 1592 {
1521 IncomingPacket incomingPacket = null; 1593 IncomingPacket incomingPacket = null;
@@ -1563,6 +1635,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1563 1635
1564 while (base.IsRunningOutbound) 1636 while (base.IsRunningOutbound)
1565 { 1637 {
1638 m_scene.ThreadAlive(2);
1566 try 1639 try
1567 { 1640 {
1568 m_packetSent = false; 1641 m_packetSent = false;
@@ -1793,8 +1866,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1793 Packet packet = incomingPacket.Packet; 1866 Packet packet = incomingPacket.Packet;
1794 LLClientView client = incomingPacket.Client; 1867 LLClientView client = incomingPacket.Client;
1795 1868
1796 if (client.IsActive) 1869// if (client.IsActive)
1797 { 1870// {
1798 m_currentIncomingClient = client; 1871 m_currentIncomingClient = client;
1799 1872
1800 try 1873 try
@@ -1821,13 +1894,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1821 { 1894 {
1822 m_currentIncomingClient = null; 1895 m_currentIncomingClient = null;
1823 } 1896 }
1824 } 1897// }
1825 else 1898// else
1826 { 1899// {
1827 m_log.DebugFormat( 1900// m_log.DebugFormat(
1828 "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", 1901// "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}",
1829 packet.Type, client.Name, m_scene.RegionInfo.RegionName); 1902// packet.Type, client.Name, m_scene.RegionInfo.RegionName);
1830 } 1903// }
1831 1904
1832 IncomingPacketsProcessed++; 1905 IncomingPacketsProcessed++;
1833 } 1906 }
@@ -1839,8 +1912,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1839 if (!client.IsLoggingOut) 1912 if (!client.IsLoggingOut)
1840 { 1913 {
1841 client.IsLoggingOut = true; 1914 client.IsLoggingOut = true;
1842 client.Close(); 1915 client.Close(false, false);
1843 } 1916 }
1844 } 1917 }
1845 } 1918 }
1846} \ No newline at end of file 1919}