diff options
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs')
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 121 |
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 | } |