mirror of
https://github.com/opensim/opensim.git
synced 2026-08-01 06:06:06 +08:00
Merge branch 'master' into careminster
Conflicts: OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs OpenSim/Region/Framework/Scenes/Scene.cs
This commit is contained in:
@@ -94,7 +94,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
|
||||
//scene.CommsManager.HttpServer.AddLLSDHandler("/CAPS/EQG/", EventQueueFallBack);
|
||||
|
||||
scene.EventManager.OnNewClient += OnNewClient;
|
||||
// scene.EventManager.OnNewClient += OnNewClient;
|
||||
|
||||
// TODO: Leaving these open, or closing them when we
|
||||
// become a child is incorrect. It messes up TP in a big
|
||||
@@ -102,6 +102,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
// circuit is there.
|
||||
|
||||
scene.EventManager.OnClientClosed += ClientClosed;
|
||||
|
||||
scene.EventManager.OnMakeChildAgent += MakeChildAgent;
|
||||
scene.EventManager.OnRegisterCaps += OnRegisterCaps;
|
||||
|
||||
@@ -226,16 +227,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
|
||||
#endregion
|
||||
|
||||
private void OnNewClient(IClientAPI client)
|
||||
{
|
||||
//client.OnLogout += ClientClosed;
|
||||
}
|
||||
|
||||
// private void ClientClosed(IClientAPI client)
|
||||
// {
|
||||
// ClientClosed(client.AgentId);
|
||||
// }
|
||||
|
||||
private void ClientClosed(UUID agentID, Scene scene)
|
||||
{
|
||||
// m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
|
||||
|
||||
@@ -47,6 +47,7 @@ using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using Timer = System.Timers.Timer;
|
||||
using AssetLandmark = OpenSim.Framework.AssetLandmark;
|
||||
using RegionFlags = OpenMetaverse.RegionFlags;
|
||||
using Nini.Config;
|
||||
|
||||
using System.IO;
|
||||
@@ -3983,7 +3984,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
{
|
||||
List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
|
||||
|
||||
ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
|
||||
ImprovedTerseObjectUpdatePacket packet
|
||||
= (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
|
||||
packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
|
||||
packet.RegionData.TimeDilation = timeDilation;
|
||||
packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
|
||||
@@ -4028,7 +4030,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
{
|
||||
List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
|
||||
|
||||
ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
|
||||
ImprovedTerseObjectUpdatePacket packet
|
||||
= (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
|
||||
PacketType.ImprovedTerseObjectUpdate);
|
||||
packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
|
||||
packet.RegionData.TimeDilation = timeDilation;
|
||||
packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
|
||||
@@ -4036,7 +4040,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
for (int i = 0; i < blocks.Count; i++)
|
||||
packet.ObjectData[i] = blocks[i];
|
||||
|
||||
OutPacket(packet, ThrottleOutPacketType.Task, true);
|
||||
OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
|
||||
}
|
||||
|
||||
#endregion Packet Sending
|
||||
@@ -5037,7 +5041,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Y, -64.0f, 64.0f), data, pos); pos += 2;
|
||||
Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Z, -64.0f, 64.0f), data, pos); pos += 2;
|
||||
|
||||
ImprovedTerseObjectUpdatePacket.ObjectDataBlock block = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock();
|
||||
ImprovedTerseObjectUpdatePacket.ObjectDataBlock block
|
||||
= PacketPool.Instance.GetDataBlock<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
|
||||
|
||||
block.Data = data;
|
||||
|
||||
if (textureEntry != null && textureEntry.Length > 0)
|
||||
@@ -11949,7 +11955,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
logPacket = false;
|
||||
|
||||
if (DebugPacketLevel <= 50
|
||||
& (packet.Type == PacketType.ImprovedTerseObjectUpdate || packet.Type == PacketType.ObjectUpdate))
|
||||
&& (packet.Type == PacketType.ImprovedTerseObjectUpdate || packet.Type == PacketType.ObjectUpdate))
|
||||
logPacket = false;
|
||||
|
||||
if (DebugPacketLevel <= 25 && packet.Type == PacketType.ObjectPropertiesFamily)
|
||||
@@ -12481,7 +12487,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
ushort timeDilation = Utils.FloatToUInt16(TIME_DILATION, 0.0f, 1.0f);
|
||||
|
||||
|
||||
ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
|
||||
ImprovedTerseObjectUpdatePacket packet
|
||||
= (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
|
||||
PacketType.ImprovedTerseObjectUpdate);
|
||||
|
||||
packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
|
||||
packet.RegionData.TimeDilation = timeDilation;
|
||||
packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
|
||||
|
||||
@@ -100,9 +100,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
/// <summary>The measured resolution of Environment.TickCount</summary>
|
||||
public readonly float TickCountResolution;
|
||||
|
||||
/// <summary>Number of prim updates to put on the queue each time the
|
||||
/// OnQueueEmpty event is triggered for updates</summary>
|
||||
public readonly int PrimUpdatesPerCallback;
|
||||
|
||||
/// <summary>Number of texture packets to put on the queue each time the
|
||||
/// OnQueueEmpty event is triggered for textures</summary>
|
||||
public readonly int TextureSendLimit;
|
||||
@@ -124,28 +126,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
/// <summary>Manages authentication for agent circuits</summary>
|
||||
private AgentCircuitManager m_circuitManager;
|
||||
|
||||
/// <summary>Reference to the scene this UDP server is attached to</summary>
|
||||
protected Scene m_scene;
|
||||
|
||||
/// <summary>The X/Y coordinates of the scene this UDP server is attached to</summary>
|
||||
private Location m_location;
|
||||
|
||||
/// <summary>The size of the receive buffer for the UDP socket. This value
|
||||
/// is passed up to the operating system and used in the system networking
|
||||
/// stack. Use zero to leave this value as the default</summary>
|
||||
private int m_recvBufferSize;
|
||||
|
||||
/// <summary>Flag to process packets asynchronously or synchronously</summary>
|
||||
private bool m_asyncPacketHandling;
|
||||
|
||||
/// <summary>Tracks whether or not a packet was sent each round so we know
|
||||
/// whether or not to sleep</summary>
|
||||
private bool m_packetSent;
|
||||
|
||||
/// <summary>Environment.TickCount of the last time that packet stats were reported to the scene</summary>
|
||||
private int m_elapsedMSSinceLastStatReport = 0;
|
||||
|
||||
/// <summary>Environment.TickCount of the last time the outgoing packet handler executed</summary>
|
||||
private int m_tickLastOutgoingPacketHandler;
|
||||
|
||||
/// <summary>Keeps track of the number of elapsed milliseconds since the last time the outgoing packet handler looped</summary>
|
||||
private int m_elapsedMSOutgoingPacketHandler;
|
||||
|
||||
/// <summary>Keeps track of the number of 100 millisecond periods elapsed in the outgoing packet handler executed</summary>
|
||||
private int m_elapsed100MSOutgoingPacketHandler;
|
||||
|
||||
/// <summary>Keeps track of the number of 500 millisecond periods elapsed in the outgoing packet handler executed</summary>
|
||||
private int m_elapsed500MSOutgoingPacketHandler;
|
||||
|
||||
@@ -425,6 +436,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
byte[] data = packet.ToBytes();
|
||||
SendPacketData(udpClient, data, packet.Type, category, method);
|
||||
}
|
||||
|
||||
PacketPool.Instance.ReturnPacket(packet);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -742,7 +755,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
try
|
||||
{
|
||||
packet = Packet.BuildPacket(buffer.Data, ref packetEnd,
|
||||
// packet = Packet.BuildPacket(buffer.Data, ref packetEnd,
|
||||
// // Only allocate a buffer for zerodecoding if the packet is zerocoded
|
||||
// ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null);
|
||||
packet = PacketPool.Instance.GetPacket(buffer.Data, ref packetEnd,
|
||||
// Only allocate a buffer for zerodecoding if the packet is zerocoded
|
||||
((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null);
|
||||
}
|
||||
@@ -757,11 +773,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
return; // Drop short packet
|
||||
}
|
||||
catch(Exception e)
|
||||
catch (Exception e)
|
||||
{
|
||||
if (m_malformedCount < 100)
|
||||
m_log.DebugFormat("[LLUDPSERVER]: Dropped malformed packet: " + e.ToString());
|
||||
|
||||
m_malformedCount++;
|
||||
|
||||
if ((m_malformedCount % 100000) == 0)
|
||||
m_log.DebugFormat("[LLUDPSERVER]: Received {0} malformed packets so far, probable network attack.", m_malformedCount);
|
||||
}
|
||||
@@ -1169,20 +1187,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
{
|
||||
IClientAPI client = null;
|
||||
|
||||
// In priciple there shouldn't be more than one thread here, ever.
|
||||
// But in case that happens, we need to synchronize this piece of code
|
||||
// because it's too important
|
||||
lock (this)
|
||||
// We currently synchronize this code across the whole scene to avoid issues such as
|
||||
// http://opensimulator.org/mantis/view.php?id=5365 However, once locking per agent circuit can be done
|
||||
// consistently, this lock could probably be removed.
|
||||
lock (this)
|
||||
{
|
||||
if (!m_scene.TryGetClient(agentID, out client))
|
||||
{
|
||||
LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO);
|
||||
|
||||
|
||||
client = new LLClientView(m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
|
||||
client.OnLogout += LogoutHandler;
|
||||
|
||||
|
||||
((LLClientView)client).DisableFacelights = m_disableFacelights;
|
||||
|
||||
|
||||
client.Start();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ using System.Reflection;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.Packets;
|
||||
using log4net;
|
||||
using OpenSim.Framework.Monitoring;
|
||||
|
||||
namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
{
|
||||
@@ -43,17 +44,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
private bool packetPoolEnabled = true;
|
||||
private bool dataBlockPoolEnabled = true;
|
||||
|
||||
private PercentageStat m_packetsReusedStat = new PercentageStat(
|
||||
"PacketsReused",
|
||||
"Packets reused",
|
||||
"clientstack",
|
||||
"packetpool",
|
||||
StatVerbosity.Debug,
|
||||
"Number of packets reused out of all requests to the packet pool");
|
||||
|
||||
private PercentageStat m_blocksReusedStat = new PercentageStat(
|
||||
"BlocksReused",
|
||||
"Blocks reused",
|
||||
"clientstack",
|
||||
"packetpool",
|
||||
StatVerbosity.Debug,
|
||||
"Number of data blocks reused out of all requests to the packet pool");
|
||||
|
||||
/// <summary>
|
||||
/// Pool of packets available for reuse.
|
||||
/// </summary>
|
||||
private readonly Dictionary<PacketType, Stack<Packet>> pool = new Dictionary<PacketType, Stack<Packet>>();
|
||||
|
||||
private static Dictionary<Type, Stack<Object>> DataBlocks =
|
||||
new Dictionary<Type, Stack<Object>>();
|
||||
|
||||
static PacketPool()
|
||||
{
|
||||
}
|
||||
private static Dictionary<Type, Stack<Object>> DataBlocks = new Dictionary<Type, Stack<Object>>();
|
||||
|
||||
public static PacketPool Instance
|
||||
{
|
||||
@@ -72,8 +84,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
get { return dataBlockPoolEnabled; }
|
||||
}
|
||||
|
||||
private PacketPool()
|
||||
{
|
||||
StatsManager.RegisterStat(m_packetsReusedStat);
|
||||
StatsManager.RegisterStat(m_blocksReusedStat);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a packet of the given type.
|
||||
/// </summary>
|
||||
/// <param name='type'></param>
|
||||
/// <returns>Guaranteed to always return a packet, whether from the pool or newly constructed.</returns>
|
||||
public Packet GetPacket(PacketType type)
|
||||
{
|
||||
m_packetsReusedStat.Consequent++;
|
||||
|
||||
Packet packet;
|
||||
|
||||
if (!packetPoolEnabled)
|
||||
@@ -89,6 +114,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
else
|
||||
{
|
||||
// Recycle old packages
|
||||
m_packetsReusedStat.Antecedent++;
|
||||
|
||||
packet = (pool[type]).Pop();
|
||||
}
|
||||
}
|
||||
@@ -138,7 +165,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
{
|
||||
PacketType type = GetType(bytes);
|
||||
|
||||
Array.Clear(zeroBuffer, 0, zeroBuffer.Length);
|
||||
// Array.Clear(zeroBuffer, 0, zeroBuffer.Length);
|
||||
|
||||
int i = 0;
|
||||
Packet packet = GetPacket(type);
|
||||
@@ -185,6 +212,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
switch (packet.Type)
|
||||
{
|
||||
// List pooling packets here
|
||||
case PacketType.AgentUpdate:
|
||||
case PacketType.PacketAck:
|
||||
case PacketType.ObjectUpdate:
|
||||
case PacketType.ImprovedTerseObjectUpdate:
|
||||
@@ -211,16 +239,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
}
|
||||
}
|
||||
|
||||
public static T GetDataBlock<T>() where T: new()
|
||||
public T GetDataBlock<T>() where T: new()
|
||||
{
|
||||
lock (DataBlocks)
|
||||
{
|
||||
m_blocksReusedStat.Consequent++;
|
||||
|
||||
Stack<Object> s;
|
||||
|
||||
if (DataBlocks.TryGetValue(typeof(T), out s))
|
||||
{
|
||||
if (s.Count > 0)
|
||||
{
|
||||
m_blocksReusedStat.Antecedent++;
|
||||
return (T)s.Pop();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -231,7 +264,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
}
|
||||
}
|
||||
|
||||
public static void ReturnDataBlock<T>(T block) where T: new()
|
||||
public void ReturnDataBlock<T>(T block) where T: new()
|
||||
{
|
||||
if (block == null)
|
||||
return;
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||
/// This will contain basic tests for the LindenUDP client stack
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class BasicCircuitTests
|
||||
public class BasicCircuitTests : OpenSimTestCase
|
||||
{
|
||||
private Scene m_scene;
|
||||
private TestLLUDPServer m_udpServer;
|
||||
@@ -143,7 +143,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||
public void TestAddClient()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// XmlConfigurator.Configure();
|
||||
// TestHelpers.EnableLogging();
|
||||
|
||||
AddUdpServer();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user