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 25e10be..544b54b 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -168,7 +168,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
168 /// <summary>Handlers for incoming packets</summary> 168 /// <summary>Handlers for incoming packets</summary>
169 //PacketEventDictionary packetEvents = new PacketEventDictionary(); 169 //PacketEventDictionary packetEvents = new PacketEventDictionary();
170 /// <summary>Incoming packets that are awaiting handling</summary> 170 /// <summary>Incoming packets that are awaiting handling</summary>
171 private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>(); 171 //private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>();
172
173 private DoubleQueue<IncomingPacket> packetInbox = new DoubleQueue<IncomingPacket>();
172 174
173 /// <summary></summary> 175 /// <summary></summary>
174 //private UDPClientCollection m_clients = new UDPClientCollection(); 176 //private UDPClientCollection m_clients = new UDPClientCollection();
@@ -223,6 +225,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
223 /// <summary>Flag to signal when clients should send pings</summary> 225 /// <summary>Flag to signal when clients should send pings</summary>
224 protected bool m_sendPing; 226 protected bool m_sendPing;
225 227
228 private ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>();
229
226 /// <summary> 230 /// <summary>
227 /// Event used to signal when queued packets are available for sending. 231 /// Event used to signal when queued packets are available for sending.
228 /// </summary> 232 /// </summary>
@@ -961,6 +965,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
961 965
962 #region Queue or Send 966 #region Queue or Send
963 967
968 bool highPriority = false;
969
970 if (category != ThrottleOutPacketType.Unknown && (category & ThrottleOutPacketType.HighPriority) != 0)
971 {
972 category = (ThrottleOutPacketType)((int)category & 127);
973 highPriority = true;
974 }
975
964 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null); 976 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null);
965 // If we were not provided a method for handling unacked, use the UDPServer default method 977 // If we were not provided a method for handling unacked, use the UDPServer default method
966 outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method); 978 outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method);
@@ -969,7 +981,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
969 // continue to display the deleted object until relog. Therefore, we need to always queue a kill object 981 // continue to display the deleted object until relog. Therefore, we need to always queue a kill object
970 // packet so that it isn't sent before a queued update packet. 982 // packet so that it isn't sent before a queued update packet.
971 bool requestQueue = type == PacketType.KillObject; 983 bool requestQueue = type == PacketType.KillObject;
972 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue)) 984 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue, highPriority))
973 SendPacketFinal(outgoingPacket); 985 SendPacketFinal(outgoingPacket);
974 986
975 #endregion Queue or Send 987 #endregion Queue or Send
@@ -1254,34 +1266,59 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1254 1266
1255 #region Packet to Client Mapping 1267 #region Packet to Client Mapping
1256 1268
1257 // UseCircuitCode handling 1269 // If there is already a client for this endpoint, don't process UseCircuitCode
1258 if (packet.Type == PacketType.UseCircuitCode) 1270 IClientAPI client = null;
1271 if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
1259 { 1272 {
1260 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the 1273 // UseCircuitCode handling
1261 // buffer. 1274 if (packet.Type == PacketType.UseCircuitCode)
1262 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; 1275 {
1276 // And if there is a UseCircuitCode pending, also drop it
1277 lock (m_pendingCache)
1278 {
1279 if (m_pendingCache.Contains(endPoint))
1280 return;
1263 1281
1264 Util.FireAndForget(HandleUseCircuitCode, array); 1282 m_pendingCache.AddOrUpdate(endPoint, new Queue<UDPPacketBuffer>(), 60);
1283 }
1265 1284
1266 return; 1285 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the
1286 // buffer.
1287 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
1288
1289 Util.FireAndForget(HandleUseCircuitCode, array);
1290
1291 return;
1292 }
1267 } 1293 }
1268 else if (packet.Type == PacketType.CompleteAgentMovement) 1294
1295 // If this is a pending connection, enqueue, don't process yet
1296 lock (m_pendingCache)
1269 { 1297 {
1270 // Send ack straight away to let the viewer know that we got it. 1298 Queue<UDPPacketBuffer> queue;
1271 SendAckImmediate(endPoint, packet.Header.Sequence); 1299 if (m_pendingCache.TryGetValue(endPoint, out queue))
1300 {
1301 //m_log.DebugFormat("[LLUDPSERVER]: Enqueued a {0} packet into the pending queue", packet.Type);
1302 queue.Enqueue(buffer);
1303 return;
1304 }
1305 else if (packet.Type == PacketType.CompleteAgentMovement)
1306 {
1307 // Send ack straight away to let the viewer know that we got it.
1308 SendAckImmediate(endPoint, packet.Header.Sequence);
1272 1309
1273 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the 1310 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the
1274 // buffer. 1311 // buffer.
1275 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; 1312 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
1276 1313
1277 Util.FireAndForget(HandleCompleteMovementIntoRegion, array); 1314 Util.FireAndForget(HandleCompleteMovementIntoRegion, array);
1278 1315
1279 return; 1316 return;
1317 }
1280 } 1318 }
1281 1319
1282 // Determine which agent this packet came from 1320 // Determine which agent this packet came from
1283 IClientAPI client; 1321 if (client == null || !(client is LLClientView))
1284 if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
1285 { 1322 {
1286 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); 1323 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName);
1287 return; 1324 return;
@@ -1290,7 +1327,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1290 udpClient = ((LLClientView)client).UDPClient; 1327 udpClient = ((LLClientView)client).UDPClient;
1291 1328
1292 if (!udpClient.IsConnected) 1329 if (!udpClient.IsConnected)
1330 {
1331 m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet for a unConnected client in " + m_scene.RegionInfo.RegionName);
1293 return; 1332 return;
1333 }
1294 1334
1295 #endregion Packet to Client Mapping 1335 #endregion Packet to Client Mapping
1296 1336
@@ -1439,7 +1479,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1439 incomingPacket = new IncomingPacket((LLClientView)client, packet); 1479 incomingPacket = new IncomingPacket((LLClientView)client, packet);
1440 } 1480 }
1441 1481
1442 packetInbox.Enqueue(incomingPacket); 1482 if (incomingPacket.Packet.Type == PacketType.AgentUpdate ||
1483 incomingPacket.Packet.Type == PacketType.ChatFromViewer)
1484 packetInbox.EnqueueHigh(incomingPacket);
1485 else
1486 packetInbox.EnqueueLow(incomingPacket);
1443 } 1487 }
1444 1488
1445 #region BinaryStats 1489 #region BinaryStats
@@ -1591,6 +1635,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1591 if (!tp) 1635 if (!tp)
1592 client.SceneAgent.SendInitialDataToMe(); 1636 client.SceneAgent.SendInitialDataToMe();
1593 } 1637 }
1638
1639 // Now we know we can handle more data
1640 Thread.Sleep(200);
1641
1642 // Obtain the queue and remove it from the cache
1643 Queue<UDPPacketBuffer> queue = null;
1644
1645 lock (m_pendingCache)
1646 {
1647 if (!m_pendingCache.TryGetValue(endPoint, out queue))
1648 {
1649 m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present");
1650 return;
1651 }
1652 m_pendingCache.Remove(endPoint);
1653 }
1654
1655 m_log.DebugFormat("[LLUDPSERVER]: Client created, processing pending queue, {0} entries", queue.Count);
1656
1657 // Reinject queued packets
1658 while(queue.Count > 0)
1659 {
1660 UDPPacketBuffer buf = queue.Dequeue();
1661 PacketReceived(buf);
1662 }
1663 queue = null;
1594 } 1664 }
1595 else 1665 else
1596 { 1666 {
@@ -1598,6 +1668,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1598 m_log.WarnFormat( 1668 m_log.WarnFormat(
1599 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", 1669 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}",
1600 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint); 1670 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint);
1671 lock (m_pendingCache)
1672 m_pendingCache.Remove(endPoint);
1601 } 1673 }
1602 1674
1603 // m_log.DebugFormat( 1675 // m_log.DebugFormat(
@@ -1783,7 +1855,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1783 if (!client.SceneAgent.IsChildAgent) 1855 if (!client.SceneAgent.IsChildAgent)
1784 client.Kick("Simulator logged you out due to connection timeout"); 1856 client.Kick("Simulator logged you out due to connection timeout");
1785 1857
1786 client.CloseWithoutChecks(); 1858 client.CloseWithoutChecks(true);
1787 } 1859 }
1788 } 1860 }
1789 1861
@@ -1795,6 +1867,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1795 1867
1796 while (IsRunningInbound) 1868 while (IsRunningInbound)
1797 { 1869 {
1870 m_scene.ThreadAlive(1);
1798 try 1871 try
1799 { 1872 {
1800 IncomingPacket incomingPacket = null; 1873 IncomingPacket incomingPacket = null;
@@ -1844,6 +1917,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1844 1917
1845 while (base.IsRunningOutbound) 1918 while (base.IsRunningOutbound)
1846 { 1919 {
1920 m_scene.ThreadAlive(2);
1847 try 1921 try
1848 { 1922 {
1849 m_packetSent = false; 1923 m_packetSent = false;
@@ -2078,8 +2152,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2078 Packet packet = incomingPacket.Packet; 2152 Packet packet = incomingPacket.Packet;
2079 LLClientView client = incomingPacket.Client; 2153 LLClientView client = incomingPacket.Client;
2080 2154
2081 if (client.IsActive) 2155// if (client.IsActive)
2082 { 2156// {
2083 m_currentIncomingClient = client; 2157 m_currentIncomingClient = client;
2084 2158
2085 try 2159 try
@@ -2106,13 +2180,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2106 { 2180 {
2107 m_currentIncomingClient = null; 2181 m_currentIncomingClient = null;
2108 } 2182 }
2109 } 2183// }
2110 else 2184// else
2111 { 2185// {
2112 m_log.DebugFormat( 2186// m_log.DebugFormat(
2113 "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", 2187// "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}",
2114 packet.Type, client.Name, m_scene.RegionInfo.RegionName); 2188// packet.Type, client.Name, m_scene.RegionInfo.RegionName);
2115 } 2189// }
2116 2190
2117 IncomingPacketsProcessed++; 2191 IncomingPacketsProcessed++;
2118 } 2192 }
@@ -2124,8 +2198,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2124 if (!client.IsLoggingOut) 2198 if (!client.IsLoggingOut)
2125 { 2199 {
2126 client.IsLoggingOut = true; 2200 client.IsLoggingOut = true;
2127 client.Close(); 2201 client.Close(false, false);
2128 } 2202 }
2129 } 2203 }
2130 } 2204 }
2131} \ No newline at end of file 2205}