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 985aa4d..33ca08c 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
@@ -1374,6 +1417,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1374 // We only want to send initial data to new clients, not ones which are being converted from child to root. 1417 // We only want to send initial data to new clients, not ones which are being converted from child to root.
1375 if (client != null) 1418 if (client != null)
1376 client.SceneAgent.SendInitialDataToMe(); 1419 client.SceneAgent.SendInitialDataToMe();
1420
1421 // Now we know we can handle more data
1422 Thread.Sleep(200);
1423
1424 // Obtain the queue and remove it from the cache
1425 Queue<UDPPacketBuffer> queue = null;
1426
1427 lock (m_pendingCache)
1428 {
1429 if (!m_pendingCache.TryGetValue(endPoint, out queue))
1430 {
1431 m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present");
1432 return;
1433 }
1434 m_pendingCache.Remove(endPoint);
1435 }
1436
1437 m_log.DebugFormat("[LLUDPSERVER]: Client created, processing pending queue, {0} entries", queue.Count);
1438
1439 // Reinject queued packets
1440 while(queue.Count > 0)
1441 {
1442 UDPPacketBuffer buf = queue.Dequeue();
1443 PacketReceived(buf);
1444 }
1445 queue = null;
1377 } 1446 }
1378 else 1447 else
1379 { 1448 {
@@ -1381,6 +1450,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1381 m_log.WarnFormat( 1450 m_log.WarnFormat(
1382 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", 1451 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}",
1383 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint); 1452 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint);
1453 lock (m_pendingCache)
1454 m_pendingCache.Remove(endPoint);
1384 } 1455 }
1385 1456
1386 // m_log.DebugFormat( 1457 // m_log.DebugFormat(
@@ -1499,7 +1570,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1499 if (!client.SceneAgent.IsChildAgent) 1570 if (!client.SceneAgent.IsChildAgent)
1500 client.Kick("Simulator logged you out due to connection timeout"); 1571 client.Kick("Simulator logged you out due to connection timeout");
1501 1572
1502 client.CloseWithoutChecks(); 1573 client.CloseWithoutChecks(true);
1503 } 1574 }
1504 } 1575 }
1505 1576
@@ -1511,6 +1582,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1511 1582
1512 while (IsRunningInbound) 1583 while (IsRunningInbound)
1513 { 1584 {
1585 m_scene.ThreadAlive(1);
1514 try 1586 try
1515 { 1587 {
1516 IncomingPacket incomingPacket = null; 1588 IncomingPacket incomingPacket = null;
@@ -1558,6 +1630,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1558 1630
1559 while (base.IsRunningOutbound) 1631 while (base.IsRunningOutbound)
1560 { 1632 {
1633 m_scene.ThreadAlive(2);
1561 try 1634 try
1562 { 1635 {
1563 m_packetSent = false; 1636 m_packetSent = false;
@@ -1788,8 +1861,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1788 Packet packet = incomingPacket.Packet; 1861 Packet packet = incomingPacket.Packet;
1789 LLClientView client = incomingPacket.Client; 1862 LLClientView client = incomingPacket.Client;
1790 1863
1791 if (client.IsActive) 1864// if (client.IsActive)
1792 { 1865// {
1793 m_currentIncomingClient = client; 1866 m_currentIncomingClient = client;
1794 1867
1795 try 1868 try
@@ -1816,13 +1889,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1816 { 1889 {
1817 m_currentIncomingClient = null; 1890 m_currentIncomingClient = null;
1818 } 1891 }
1819 } 1892// }
1820 else 1893// else
1821 { 1894// {
1822 m_log.DebugFormat( 1895// m_log.DebugFormat(
1823 "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", 1896// "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}",
1824 packet.Type, client.Name, m_scene.RegionInfo.RegionName); 1897// packet.Type, client.Name, m_scene.RegionInfo.RegionName);
1825 } 1898// }
1826 1899
1827 IncomingPacketsProcessed++; 1900 IncomingPacketsProcessed++;
1828 } 1901 }
@@ -1834,8 +1907,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1834 if (!client.IsLoggingOut) 1907 if (!client.IsLoggingOut)
1835 { 1908 {
1836 client.IsLoggingOut = true; 1909 client.IsLoggingOut = true;
1837 client.Close(); 1910 client.Close(false, false);
1838 } 1911 }
1839 } 1912 }
1840 } 1913 }
1841} \ No newline at end of file 1914}