aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden')
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs9
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs96
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs3
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs117
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs6
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs33
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs7
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs175
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs468
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs101
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs306
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs33
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs7
22 files changed, 1103 insertions, 278 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
index 650cd50..f6146a9 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
@@ -241,8 +241,8 @@ namespace OpenSim.Region.ClientStack.Linden
241 m_HostCapsObj.RegisterHandler( 241 m_HostCapsObj.RegisterHandler(
242 "SEED", new RestStreamHandler("POST", capsBase + m_requestPath, SeedCapRequest, "SEED", null)); 242 "SEED", new RestStreamHandler("POST", capsBase + m_requestPath, SeedCapRequest, "SEED", null));
243 243
244 m_log.DebugFormat( 244// m_log.DebugFormat(
245 "[CAPS]: Registered seed capability {0} for {1}", capsBase + m_requestPath, m_HostCapsObj.AgentID); 245// "[CAPS]: Registered seed capability {0} for {1}", capsBase + m_requestPath, m_HostCapsObj.AgentID);
246 246
247 //m_capsHandlers["MapLayer"] = 247 //m_capsHandlers["MapLayer"] =
248 // new LLSDStreamhandler<OSDMapRequest, OSDMapLayerResponse>("POST", 248 // new LLSDStreamhandler<OSDMapRequest, OSDMapLayerResponse>("POST",
@@ -337,11 +337,12 @@ namespace OpenSim.Region.ClientStack.Linden
337 public string SeedCapRequest(string request, string path, string param, 337 public string SeedCapRequest(string request, string path, string param,
338 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) 338 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
339 { 339 {
340// m_log.Debug("[CAPS]: Seed Caps Request in region: " + m_regionName); 340 m_log.DebugFormat(
341 "[CAPS]: Received SEED caps request in {0} for agent {1}", m_regionName, m_HostCapsObj.AgentID);
341 342
342 if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint)) 343 if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint))
343 { 344 {
344 m_log.DebugFormat( 345 m_log.WarnFormat(
345 "[CAPS]: Unauthorized CAPS client {0} from {1}", 346 "[CAPS]: Unauthorized CAPS client {0} from {1}",
346 m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint); 347 m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint);
347 348
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs
index 66b865f..b735dfa 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs
@@ -45,7 +45,7 @@ using Caps = OpenSim.Framework.Capabilities.Caps;
45namespace OpenSim.Region.ClientStack.Linden 45namespace OpenSim.Region.ClientStack.Linden
46{ 46{
47 47
48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "BunchOfCapsModule")]
49 public class BunchOfCapsModule : INonSharedRegionModule 49 public class BunchOfCapsModule : INonSharedRegionModule
50 { 50 {
51// private static readonly ILog m_log = 51// private static readonly ILog m_log =
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
index e113c60..986a665 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
@@ -55,8 +55,8 @@ namespace OpenSim.Region.ClientStack.Linden
55 public OSDMap body; 55 public OSDMap body;
56 } 56 }
57 57
58 //[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 58 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "EventQueueGetModule")]
59 public class EventQueueGetModule : IEventQueue, IRegionModule 59 public class EventQueueGetModule : IEventQueue, INonSharedRegionModule
60 { 60 {
61 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 61 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
62 62
@@ -66,8 +66,6 @@ namespace OpenSim.Region.ClientStack.Linden
66 public int DebugLevel { get; set; } 66 public int DebugLevel { get; set; }
67 67
68 protected Scene m_scene; 68 protected Scene m_scene;
69 private IConfigSource m_gConfig;
70 bool enabledYN;
71 69
72 private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>(); 70 private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>();
73 71
@@ -75,59 +73,46 @@ namespace OpenSim.Region.ClientStack.Linden
75 private Dictionary<UUID, UUID> m_QueueUUIDAvatarMapping = new Dictionary<UUID, UUID>(); 73 private Dictionary<UUID, UUID> m_QueueUUIDAvatarMapping = new Dictionary<UUID, UUID>();
76 private Dictionary<UUID, UUID> m_AvatarQueueUUIDMapping = new Dictionary<UUID, UUID>(); 74 private Dictionary<UUID, UUID> m_AvatarQueueUUIDMapping = new Dictionary<UUID, UUID>();
77 75
78 #region IRegionModule methods 76 #region INonSharedRegionModule methods
79 public virtual void Initialise(Scene scene, IConfigSource config) 77 public virtual void Initialise(IConfigSource config)
80 { 78 {
81 m_gConfig = config; 79 }
82 80
83 IConfig startupConfig = m_gConfig.Configs["Startup"]; 81 public void AddRegion(Scene scene)
82 {
83 m_scene = scene;
84 scene.RegisterModuleInterface<IEventQueue>(this);
84 85
85 ReadConfigAndPopulate(scene, startupConfig, "Startup"); 86 scene.EventManager.OnClientClosed += ClientClosed;
87 scene.EventManager.OnMakeChildAgent += MakeChildAgent;
88 scene.EventManager.OnRegisterCaps += OnRegisterCaps;
86 89
87 if (enabledYN) 90 MainConsole.Instance.Commands.AddCommand(
88 { 91 "Debug",
89 m_scene = scene; 92 false,
90 scene.RegisterModuleInterface<IEventQueue>(this); 93 "debug eq",
91 94 "debug eq [0|1|2]",
92 // Register fallback handler 95 "Turn on event queue debugging\n"
93 // Why does EQG Fail on region crossings! 96 + " <= 0 - turns off all event queue logging\n"
94 97 + " >= 1 - turns on outgoing event logging\n"
95 //scene.CommsManager.HttpServer.AddLLSDHandler("/CAPS/EQG/", EventQueueFallBack); 98 + " >= 2 - turns on poll notification",
96 99 HandleDebugEq);
97 scene.EventManager.OnNewClient += OnNewClient;
98
99 // TODO: Leaving these open, or closing them when we
100 // become a child is incorrect. It messes up TP in a big
101 // way. CAPS/EQ need to be active as long as the UDP
102 // circuit is there.
103
104 scene.EventManager.OnClientClosed += ClientClosed;
105 scene.EventManager.OnMakeChildAgent += MakeChildAgent;
106 scene.EventManager.OnRegisterCaps += OnRegisterCaps;
107
108 MainConsole.Instance.Commands.AddCommand(
109 "Debug",
110 false,
111 "debug eq",
112 "debug eq [0|1|2]",
113 "Turn on event queue debugging"
114 + "<= 0 - turns off all event queue logging"
115 + ">= 1 - turns on outgoing event logging"
116 + ">= 2 - turns on poll notification",
117 HandleDebugEq);
118 }
119 else
120 {
121 m_gConfig = null;
122 }
123 } 100 }
124 101
125 private void ReadConfigAndPopulate(Scene scene, IConfig startupConfig, string p) 102 public void RemoveRegion(Scene scene)
126 { 103 {
127 enabledYN = startupConfig.GetBoolean("EventQueue", true); 104 if (m_scene != scene)
105 return;
106
107 scene.EventManager.OnClientClosed -= ClientClosed;
108 scene.EventManager.OnMakeChildAgent -= MakeChildAgent;
109 scene.EventManager.OnRegisterCaps -= OnRegisterCaps;
110
111 scene.UnregisterModuleInterface<IEventQueue>(this);
112 m_scene = null;
128 } 113 }
129 114
130 public void PostInitialise() 115 public void RegionLoaded(Scene scene)
131 { 116 {
132 } 117 }
133 118
@@ -140,10 +125,11 @@ namespace OpenSim.Region.ClientStack.Linden
140 get { return "EventQueueGetModule"; } 125 get { return "EventQueueGetModule"; }
141 } 126 }
142 127
143 public bool IsSharedModule 128 public Type ReplaceableInterface
144 { 129 {
145 get { return false; } 130 get { return null; }
146 } 131 }
132
147 #endregion 133 #endregion
148 134
149 protected void HandleDebugEq(string module, string[] args) 135 protected void HandleDebugEq(string module, string[] args)
@@ -226,16 +212,6 @@ namespace OpenSim.Region.ClientStack.Linden
226 212
227 #endregion 213 #endregion
228 214
229 private void OnNewClient(IClientAPI client)
230 {
231 //client.OnLogout += ClientClosed;
232 }
233
234// private void ClientClosed(IClientAPI client)
235// {
236// ClientClosed(client.AgentId);
237// }
238
239 private void ClientClosed(UUID agentID, Scene scene) 215 private void ClientClosed(UUID agentID, Scene scene)
240 { 216 {
241// m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", agentID, m_scene.RegionInfo.RegionName); 217// m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
index cd70410..d604cf6 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
@@ -94,7 +94,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
94 UUID spId = TestHelpers.ParseTail(0x1); 94 UUID spId = TestHelpers.ParseTail(0x1);
95 95
96 SceneHelpers.AddScenePresence(m_scene, spId); 96 SceneHelpers.AddScenePresence(m_scene, spId);
97 m_scene.IncomingCloseAgent(spId); 97 m_scene.IncomingCloseAgent(spId, false);
98 98
99 // TODO: Add more assertions for the other aspects of event queues 99 // TODO: Add more assertions for the other aspects of event queues
100 Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(0)); 100 Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(0));
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs b/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs
index cb5afcc..87d3d1c 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs
@@ -45,7 +45,7 @@ namespace OpenSim.Region.ClientStack.Linden
45 /// <summary> 45 /// <summary>
46 /// This module implements both WebFetchInventoryDescendents and FetchInventoryDescendents2 capabilities. 46 /// This module implements both WebFetchInventoryDescendents and FetchInventoryDescendents2 capabilities.
47 /// </summary> 47 /// </summary>
48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "FetchInventory2Module")]
49 public class FetchInventory2Module : INonSharedRegionModule 49 public class FetchInventory2Module : INonSharedRegionModule
50 { 50 {
51// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 51// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
index 8deff81..e6d7db8 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
@@ -50,7 +50,7 @@ using Caps = OpenSim.Framework.Capabilities.Caps;
50 50
51namespace OpenSim.Region.ClientStack.Linden 51namespace OpenSim.Region.ClientStack.Linden
52{ 52{
53 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 53 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GetMeshModule")]
54 public class GetMeshModule : INonSharedRegionModule 54 public class GetMeshModule : INonSharedRegionModule
55 { 55 {
56// private static readonly ILog m_log = 56// private static readonly ILog m_log =
@@ -88,7 +88,7 @@ namespace OpenSim.Region.ClientStack.Linden
88 88
89 private Dictionary<UUID, PollServiceMeshEventArgs> m_pollservices = new Dictionary<UUID, PollServiceMeshEventArgs>(); 89 private Dictionary<UUID, PollServiceMeshEventArgs> m_pollservices = new Dictionary<UUID, PollServiceMeshEventArgs>();
90 90
91 #region ISharedRegionModule Members 91 #region Region Module interfaceBase Members
92 92
93 ~GetMeshModule() 93 ~GetMeshModule()
94 { 94 {
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
index c8c709a..dd87671 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
@@ -47,9 +47,6 @@ using OpenSim.Framework.Monitoring;
47namespace OpenSim.Region.ClientStack.Linden 47namespace OpenSim.Region.ClientStack.Linden
48{ 48{
49 49
50 /// <summary>
51 /// This module implements both WebFetchTextureDescendents and FetchTextureDescendents2 capabilities.
52 /// </summary>
53 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GetTextureModule")] 50 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GetTextureModule")]
54 public class GetTextureModule : INonSharedRegionModule 51 public class GetTextureModule : INonSharedRegionModule
55 { 52 {
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs
index 0251ac4..60c1814 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs
@@ -45,7 +45,7 @@ namespace OpenSim.Region.ClientStack.Linden
45 /// <summary> 45 /// <summary>
46 /// MeshUploadFlag capability. This is required for uploading Mesh. 46 /// MeshUploadFlag capability. This is required for uploading Mesh.
47 /// </summary> 47 /// </summary>
48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "MeshUploadFlagModule")]
49 public class MeshUploadFlagModule : INonSharedRegionModule 49 public class MeshUploadFlagModule : INonSharedRegionModule
50 { 50 {
51// private static readonly ILog m_log = 51// private static readonly ILog m_log =
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs
index 4ccfc43..92805e2 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs
@@ -32,6 +32,7 @@ using log4net;
32using Nini.Config; 32using Nini.Config;
33using OpenMetaverse; 33using OpenMetaverse;
34using OpenMetaverse.StructuredData; 34using OpenMetaverse.StructuredData;
35using Mono.Addins;
35using OpenSim.Framework; 36using OpenSim.Framework;
36using OpenSim.Framework.Servers; 37using OpenSim.Framework.Servers;
37using OpenSim.Framework.Servers.HttpServer; 38using OpenSim.Framework.Servers.HttpServer;
@@ -41,30 +42,60 @@ using Caps=OpenSim.Framework.Capabilities.Caps;
41 42
42namespace OpenSim.Region.ClientStack.Linden 43namespace OpenSim.Region.ClientStack.Linden
43{ 44{
44 public class ObjectAdd : IRegionModule 45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ObjectAdd")]
46 public class ObjectAdd : INonSharedRegionModule
45 { 47 {
46// private static readonly ILog m_log = 48// private static readonly ILog m_log =
47// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 49// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48 50
49 private Scene m_scene; 51 private Scene m_scene;
50 #region IRegionModule Members
51 52
52 public void Initialise(Scene pScene, IConfigSource pSource) 53 #region INonSharedRegionModule Members
54
55 public void Initialise(IConfigSource pSource)
56 {
57 }
58
59 public void AddRegion(Scene scene)
53 { 60 {
54 m_scene = pScene; 61 m_scene = scene;
55 m_scene.EventManager.OnRegisterCaps += RegisterCaps; 62 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
56 } 63 }
57 64
58 public void PostInitialise() 65 public void RemoveRegion(Scene scene)
59 { 66 {
60 67 if (m_scene == scene)
68 {
69 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
70 m_scene = null;
71 }
61 } 72 }
62 73
74 public void RegionLoaded(Scene scene)
75 {
76 }
77
78 public void Close()
79 {
80 }
81
82 public string Name
83 {
84 get { return "ObjectAddModule"; }
85 }
86
87 public Type ReplaceableInterface
88 {
89 get { return null; }
90 }
91
92 #endregion
93
63 public void RegisterCaps(UUID agentID, Caps caps) 94 public void RegisterCaps(UUID agentID, Caps caps)
64 { 95 {
65 UUID capuuid = UUID.Random(); 96 UUID capuuid = UUID.Random();
66 97
67// m_log.InfoFormat("[OBJECTADD]: {0}", "/CAPS/OA/" + capuuid + "/"); 98 // m_log.InfoFormat("[OBJECTADD]: {0}", "/CAPS/OA/" + capuuid + "/");
68 99
69 caps.RegisterHandler( 100 caps.RegisterHandler(
70 "ObjectAdd", 101 "ObjectAdd",
@@ -73,7 +104,7 @@ namespace OpenSim.Region.ClientStack.Linden
73 "/CAPS/OA/" + capuuid + "/", 104 "/CAPS/OA/" + capuuid + "/",
74 httpMethod => ProcessAdd(httpMethod, agentID, caps), 105 httpMethod => ProcessAdd(httpMethod, agentID, caps),
75 "ObjectAdd", 106 "ObjectAdd",
76 agentID.ToString()));; 107 agentID.ToString())); ;
77 } 108 }
78 109
79 public Hashtable ProcessAdd(Hashtable request, UUID AgentId, Caps cap) 110 public Hashtable ProcessAdd(Hashtable request, UUID AgentId, Caps cap)
@@ -84,7 +115,7 @@ namespace OpenSim.Region.ClientStack.Linden
84 responsedata["keepalive"] = false; 115 responsedata["keepalive"] = false;
85 responsedata["str_response_string"] = "Request wasn't what was expected"; 116 responsedata["str_response_string"] = "Request wasn't what was expected";
86 ScenePresence avatar; 117 ScenePresence avatar;
87 118
88 if (!m_scene.TryGetScenePresence(AgentId, out avatar)) 119 if (!m_scene.TryGetScenePresence(AgentId, out avatar))
89 return responsedata; 120 return responsedata;
90 121
@@ -127,7 +158,7 @@ namespace OpenSim.Region.ClientStack.Linden
127 158
128 if (r.Type != OSDType.Map) // not a proper req 159 if (r.Type != OSDType.Map) // not a proper req
129 return responsedata; 160 return responsedata;
130 161
131 OSDMap rm = (OSDMap)r; 162 OSDMap rm = (OSDMap)r;
132 163
133 if (rm.ContainsKey("ObjectData")) //v2 164 if (rm.ContainsKey("ObjectData")) //v2
@@ -138,7 +169,7 @@ namespace OpenSim.Region.ClientStack.Linden
138 return responsedata; 169 return responsedata;
139 } 170 }
140 171
141 OSDMap ObjMap = (OSDMap) rm["ObjectData"]; 172 OSDMap ObjMap = (OSDMap)rm["ObjectData"];
142 173
143 bypass_raycast = ObjMap["BypassRaycast"].AsBoolean(); 174 bypass_raycast = ObjMap["BypassRaycast"].AsBoolean();
144 everyone_mask = readuintval(ObjMap["EveryoneMask"]); 175 everyone_mask = readuintval(ObjMap["EveryoneMask"]);
@@ -181,7 +212,7 @@ namespace OpenSim.Region.ClientStack.Linden
181 responsedata["str_response_string"] = "Has Profile key, but data not in expected format"; 212 responsedata["str_response_string"] = "Has Profile key, but data not in expected format";
182 return responsedata; 213 return responsedata;
183 } 214 }
184 215
185 OSDMap ProfileMap = (OSDMap)ObjMap["Profile"]; 216 OSDMap ProfileMap = (OSDMap)ObjMap["Profile"];
186 217
187 profile_begin = ProfileMap["Begin"].AsInteger(); 218 profile_begin = ProfileMap["Begin"].AsInteger();
@@ -190,14 +221,14 @@ namespace OpenSim.Region.ClientStack.Linden
190 hollow = ProfileMap["Hollow"].AsInteger(); 221 hollow = ProfileMap["Hollow"].AsInteger();
191 } 222 }
192 ray_end_is_intersection = ObjMap["RayEndIsIntersection"].AsBoolean(); 223 ray_end_is_intersection = ObjMap["RayEndIsIntersection"].AsBoolean();
193 224
194 ray_target_id = ObjMap["RayTargetId"].AsUUID(); 225 ray_target_id = ObjMap["RayTargetId"].AsUUID();
195 state = ObjMap["State"].AsInteger(); 226 state = ObjMap["State"].AsInteger();
196 try 227 try
197 { 228 {
198 ray_end = ((OSDArray) ObjMap["RayEnd"]).AsVector3(); 229 ray_end = ((OSDArray)ObjMap["RayEnd"]).AsVector3();
199 ray_start = ((OSDArray) ObjMap["RayStart"]).AsVector3(); 230 ray_start = ((OSDArray)ObjMap["RayStart"]).AsVector3();
200 scale = ((OSDArray) ObjMap["Scale"]).AsVector3(); 231 scale = ((OSDArray)ObjMap["Scale"]).AsVector3();
201 rotation = ((OSDArray)ObjMap["Rotation"]).AsQuaternion(); 232 rotation = ((OSDArray)ObjMap["Rotation"]).AsQuaternion();
202 } 233 }
203 catch (Exception) 234 catch (Exception)
@@ -214,7 +245,7 @@ namespace OpenSim.Region.ClientStack.Linden
214 return responsedata; 245 return responsedata;
215 } 246 }
216 247
217 OSDMap AgentDataMap = (OSDMap) rm["AgentData"]; 248 OSDMap AgentDataMap = (OSDMap)rm["AgentData"];
218 249
219 //session_id = AgentDataMap["SessionId"].AsUUID(); 250 //session_id = AgentDataMap["SessionId"].AsUUID();
220 group_id = AgentDataMap["GroupId"].AsUUID(); 251 group_id = AgentDataMap["GroupId"].AsUUID();
@@ -251,21 +282,21 @@ namespace OpenSim.Region.ClientStack.Linden
251 profile_begin = rm["profile_begin"].AsInteger(); 282 profile_begin = rm["profile_begin"].AsInteger();
252 profile_curve = rm["profile_curve"].AsInteger(); 283 profile_curve = rm["profile_curve"].AsInteger();
253 profile_end = rm["profile_end"].AsInteger(); 284 profile_end = rm["profile_end"].AsInteger();
254 285
255 ray_end_is_intersection = rm["ray_end_is_intersection"].AsBoolean(); 286 ray_end_is_intersection = rm["ray_end_is_intersection"].AsBoolean();
256 287
257 ray_target_id = rm["ray_target_id"].AsUUID(); 288 ray_target_id = rm["ray_target_id"].AsUUID();
258 289
259 290
260 //session_id = rm["session_id"].AsUUID(); 291 //session_id = rm["session_id"].AsUUID();
261 state = rm["state"].AsInteger(); 292 state = rm["state"].AsInteger();
262 try 293 try
263 { 294 {
264 ray_end = ((OSDArray)rm["ray_end"]).AsVector3(); 295 ray_end = ((OSDArray)rm["ray_end"]).AsVector3();
265 ray_start = ((OSDArray)rm["ray_start"]).AsVector3(); 296 ray_start = ((OSDArray)rm["ray_start"]).AsVector3();
266 rotation = ((OSDArray)rm["rotation"]).AsQuaternion(); 297 rotation = ((OSDArray)rm["rotation"]).AsQuaternion();
267 scale = ((OSDArray)rm["scale"]).AsVector3(); 298 scale = ((OSDArray)rm["scale"]).AsVector3();
268 } 299 }
269 catch (Exception) 300 catch (Exception)
270 { 301 {
271 responsedata["str_response_string"] = "RayEnd, RayStart, Scale or Rotation wasn't in the expected format"; 302 responsedata["str_response_string"] = "RayEnd, RayStart, Scale or Rotation wasn't in the expected format";
@@ -273,9 +304,9 @@ namespace OpenSim.Region.ClientStack.Linden
273 } 304 }
274 } 305 }
275 306
276
277 307
278 Vector3 pos = m_scene.GetNewRezLocation(ray_start, ray_end, ray_target_id, rotation, (bypass_raycast) ? (byte)1 : (byte)0, (ray_end_is_intersection) ? (byte)1 : (byte)0, true, scale, false); 308
309 Vector3 pos = m_scene.GetNewRezLocation(ray_start, ray_end, ray_target_id, rotation, (bypass_raycast) ? (byte)1 : (byte)0, (ray_end_is_intersection) ? (byte)1 : (byte)0, true, scale, false);
279 310
280 PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox(); 311 PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox();
281 312
@@ -286,17 +317,17 @@ namespace OpenSim.Region.ClientStack.Linden
286 pbs.PathRevolutions = (byte)path_revolutions; 317 pbs.PathRevolutions = (byte)path_revolutions;
287 pbs.PathScaleX = (byte)path_scale_x; 318 pbs.PathScaleX = (byte)path_scale_x;
288 pbs.PathScaleY = (byte)path_scale_y; 319 pbs.PathScaleY = (byte)path_scale_y;
289 pbs.PathShearX = (byte) path_shear_x; 320 pbs.PathShearX = (byte)path_shear_x;
290 pbs.PathShearY = (byte)path_shear_y; 321 pbs.PathShearY = (byte)path_shear_y;
291 pbs.PathSkew = (sbyte)path_skew; 322 pbs.PathSkew = (sbyte)path_skew;
292 pbs.PathTaperX = (sbyte)path_taper_x; 323 pbs.PathTaperX = (sbyte)path_taper_x;
293 pbs.PathTaperY = (sbyte)path_taper_y; 324 pbs.PathTaperY = (sbyte)path_taper_y;
294 pbs.PathTwist = (sbyte)path_twist; 325 pbs.PathTwist = (sbyte)path_twist;
295 pbs.PathTwistBegin = (sbyte)path_twist_begin; 326 pbs.PathTwistBegin = (sbyte)path_twist_begin;
296 pbs.HollowShape = (HollowShape) hollow; 327 pbs.HollowShape = (HollowShape)hollow;
297 pbs.PCode = (byte)p_code; 328 pbs.PCode = (byte)p_code;
298 pbs.ProfileBegin = (ushort) profile_begin; 329 pbs.ProfileBegin = (ushort)profile_begin;
299 pbs.ProfileCurve = (byte) profile_curve; 330 pbs.ProfileCurve = (byte)profile_curve;
300 pbs.ProfileEnd = (ushort)profile_end; 331 pbs.ProfileEnd = (ushort)profile_end;
301 pbs.Scale = scale; 332 pbs.Scale = scale;
302 pbs.State = (byte)state; 333 pbs.State = (byte)state;
@@ -306,7 +337,7 @@ namespace OpenSim.Region.ClientStack.Linden
306 if (m_scene.Permissions.CanRezObject(1, avatar.UUID, pos)) 337 if (m_scene.Permissions.CanRezObject(1, avatar.UUID, pos))
307 { 338 {
308 // rez ON the ground, not IN the ground 339 // rez ON the ground, not IN the ground
309 // pos.Z += 0.25F; 340 // pos.Z += 0.25F;
310 341
311 obj = m_scene.AddNewPrim(avatar.UUID, group_id, pos, rotation, pbs); 342 obj = m_scene.AddNewPrim(avatar.UUID, group_id, pos, rotation, pbs);
312 } 343 }
@@ -323,13 +354,13 @@ namespace OpenSim.Region.ClientStack.Linden
323 rootpart.GroupMask = group_mask; 354 rootpart.GroupMask = group_mask;
324 rootpart.NextOwnerMask = next_owner_mask; 355 rootpart.NextOwnerMask = next_owner_mask;
325 rootpart.Material = (byte)material; 356 rootpart.Material = (byte)material;
326 357
327 m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor); 358 m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor);
328 359
329 responsedata["int_response_code"] = 200; //501; //410; //404; 360 responsedata["int_response_code"] = 200; //501; //410; //404;
330 responsedata["content_type"] = "text/plain"; 361 responsedata["content_type"] = "text/plain";
331 responsedata["keepalive"] = false; 362 responsedata["keepalive"] = false;
332 responsedata["str_response_string"] = String.Format("<llsd><map><key>local_id</key>{0}</map></llsd>",ConvertUintToBytes(obj.LocalId)); 363 responsedata["str_response_string"] = String.Format("<llsd><map><key>local_id</key>{0}</map></llsd>", ConvertUintToBytes(obj.LocalId));
333 364
334 return responsedata; 365 return responsedata;
335 } 366 }
@@ -347,24 +378,8 @@ namespace OpenSim.Region.ClientStack.Linden
347 byte[] resultbytes = Utils.UIntToBytes(val); 378 byte[] resultbytes = Utils.UIntToBytes(val);
348 if (BitConverter.IsLittleEndian) 379 if (BitConverter.IsLittleEndian)
349 Array.Reverse(resultbytes); 380 Array.Reverse(resultbytes);
350 return String.Format("<binary encoding=\"base64\">{0}</binary>",Convert.ToBase64String(resultbytes)); 381 return String.Format("<binary encoding=\"base64\">{0}</binary>", Convert.ToBase64String(resultbytes));
351 }
352
353 public void Close()
354 {
355
356 }
357
358 public string Name
359 {
360 get { return "ObjectAddModule"; }
361 }
362
363 public bool IsSharedModule
364 {
365 get { return false; }
366 } 382 }
367 383
368 #endregion
369 } 384 }
370} 385}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs
index ba902b2..55a503e 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs
@@ -51,14 +51,14 @@ using ExtraParamType = OpenMetaverse.ExtraParamType;
51 51
52namespace OpenSim.Region.ClientStack.Linden 52namespace OpenSim.Region.ClientStack.Linden
53{ 53{
54 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 54 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UploadObjectAssetModule")]
55 public class UploadObjectAssetModule : INonSharedRegionModule 55 public class UploadObjectAssetModule : INonSharedRegionModule
56 { 56 {
57 private static readonly ILog m_log = 57 private static readonly ILog m_log =
58 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 58 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
59 private Scene m_scene; 59 private Scene m_scene;
60 60
61 #region IRegionModuleBase Members 61 #region Region Module interfaceBase Members
62 62
63 63
64 public Type ReplaceableInterface 64 public Type ReplaceableInterface
@@ -92,7 +92,7 @@ namespace OpenSim.Region.ClientStack.Linden
92 #endregion 92 #endregion
93 93
94 94
95 #region IRegionModule Members 95 #region Region Module interface
96 96
97 97
98 98
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs b/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..060a61c
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs
@@ -0,0 +1,33 @@
1using System.Reflection;
2using System.Runtime.CompilerServices;
3using System.Runtime.InteropServices;
4
5// General Information about an assembly is controlled through the following
6// set of attributes. Change these attribute values to modify the information
7// associated with an assembly.
8[assembly: AssemblyTitle("OpenSim.Region.ClientStack.LindenCaps")]
9[assembly: AssemblyDescription("")]
10[assembly: AssemblyConfiguration("")]
11[assembly: AssemblyCompany("http://opensimulator.org")]
12[assembly: AssemblyProduct("OpenSim")]
13[assembly: AssemblyCopyright("OpenSimulator developers")]
14[assembly: AssemblyTrademark("")]
15[assembly: AssemblyCulture("")]
16
17// Setting ComVisible to false makes the types in this assembly not visible
18// to COM components. If you need to access a type in this assembly from
19// COM, set the ComVisible attribute to true on that type.
20[assembly: ComVisible(false)]
21
22// The following GUID is for the ID of the typelib if this project is exposed to COM
23[assembly: Guid("1ae76353-f37f-4fe3-b6df-d11cedf01f2c")]
24
25// Version information for an assembly consists of the following four values:
26//
27// Major Version
28// Minor Version
29// Build Number
30// Revision
31//
32[assembly: AssemblyVersion("0.7.5.*")]
33[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs
index 0a5ad0f..fcac182 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs
@@ -109,7 +109,7 @@ namespace OpenSim.Region.ClientStack.Linden
109 109
110 UUID capID = UUID.Random(); 110 UUID capID = UUID.Random();
111 111
112 m_log.DebugFormat("[REGION CONSOLE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); 112// m_log.DebugFormat("[REGION CONSOLE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
113 caps.RegisterHandler( 113 caps.RegisterHandler(
114 "SimConsoleAsync", 114 "SimConsoleAsync",
115 new ConsoleHandler("/CAPS/" + capID + "/", "SimConsoleAsync", agentID, this, m_scene)); 115 new ConsoleHandler("/CAPS/" + capID + "/", "SimConsoleAsync", agentID, this, m_scene));
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs
index 8ed0fb3..191bccf 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs
@@ -53,7 +53,7 @@ namespace OpenSim.Region.ClientStack.Linden
53 /// NOTE: Part of this code was adapted from the Aurora project, specifically 53 /// NOTE: Part of this code was adapted from the Aurora project, specifically
54 /// the normal part of the response in the capability handler. 54 /// the normal part of the response in the capability handler.
55 /// </remarks> 55 /// </remarks>
56 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 56 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SimulatorFeaturesModule")]
57 public class SimulatorFeaturesModule : ISharedRegionModule, ISimulatorFeaturesModule 57 public class SimulatorFeaturesModule : ISharedRegionModule, ISimulatorFeaturesModule
58 { 58 {
59// private static readonly ILog m_log = 59// private static readonly ILog m_log =
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs
index 6aac591..3b0ccd7 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs
@@ -50,7 +50,7 @@ using OpenSim.Capabilities.Handlers;
50 50
51namespace OpenSim.Region.ClientStack.Linden 51namespace OpenSim.Region.ClientStack.Linden
52{ 52{
53 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 53 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UploadBakedTextureModule")]
54 public class UploadBakedTextureModule : INonSharedRegionModule 54 public class UploadBakedTextureModule : INonSharedRegionModule
55 { 55 {
56// private static readonly ILog m_log = 56// private static readonly ILog m_log =
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
index 0caeddf..04cd474 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
@@ -49,7 +49,7 @@ namespace OpenSim.Region.ClientStack.Linden
49 /// <summary> 49 /// <summary>
50 /// This module implements both WebFetchInventoryDescendents and FetchInventoryDescendents2 capabilities. 50 /// This module implements both WebFetchInventoryDescendents and FetchInventoryDescendents2 capabilities.
51 /// </summary> 51 /// </summary>
52 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 52 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "WebFetchInvDescModule")]
53 public class WebFetchInvDescModule : INonSharedRegionModule 53 public class WebFetchInvDescModule : INonSharedRegionModule
54 { 54 {
55 struct aPollRequest 55 struct aPollRequest
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs b/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs
index 1b8535c..e22670b 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs
@@ -45,7 +45,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
45 public Packet Packet; 45 public Packet Packet;
46 46
47 /// <summary> 47 /// <summary>
48 /// Default constructor 48 /// No arg constructor.
49 /// </summary>
50 public IncomingPacket() {}
51
52 /// <summary>
53 /// Constructor
49 /// </summary> 54 /// </summary>
50 /// <param name="client">Reference to the client this packet came from</param> 55 /// <param name="client">Reference to the client this packet came from</param>
51 /// <param name="packet">Packet data</param> 56 /// <param name="packet">Packet data</param>
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index ae9ed7f..5551f51 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -47,6 +47,7 @@ using OpenSim.Region.Framework.Scenes;
47using OpenSim.Services.Interfaces; 47using OpenSim.Services.Interfaces;
48using Timer = System.Timers.Timer; 48using Timer = System.Timers.Timer;
49using AssetLandmark = OpenSim.Framework.AssetLandmark; 49using AssetLandmark = OpenSim.Framework.AssetLandmark;
50using RegionFlags = OpenMetaverse.RegionFlags;
50using Nini.Config; 51using Nini.Config;
51 52
52using System.IO; 53using System.IO;
@@ -355,7 +356,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
355 private bool m_deliverPackets = true; 356 private bool m_deliverPackets = true;
356 private int m_animationSequenceNumber = 1; 357 private int m_animationSequenceNumber = 1;
357 private bool m_SendLogoutPacketWhenClosing = true; 358 private bool m_SendLogoutPacketWhenClosing = true;
358 private AgentUpdateArgs lastarg; 359
360 /// <summary>
361 /// We retain a single AgentUpdateArgs so that we can constantly reuse it rather than construct a new one for
362 /// every single incoming AgentUpdate. Every client sends 10 AgentUpdate UDP messages per second, even if it
363 /// is doing absolutely nothing.
364 /// </summary>
365 /// <remarks>
366 /// This does mean that agent updates must be processed synchronously, at least for each client, and called methods
367 /// cannot retain a reference to it outside of that method.
368 /// </remarks>
369 private AgentUpdateArgs m_lastAgentUpdateArgs;
359 370
360 protected Dictionary<PacketType, PacketProcessor> m_packetHandlers = new Dictionary<PacketType, PacketProcessor>(); 371 protected Dictionary<PacketType, PacketProcessor> m_packetHandlers = new Dictionary<PacketType, PacketProcessor>();
361 protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers 372 protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers
@@ -510,19 +521,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
510 /// </summary> 521 /// </summary>
511 public void Close() 522 public void Close()
512 { 523 {
513 Close(true); 524 Close(true, false);
514 } 525 }
515 526
516 /// <summary> 527 public void Close(bool sendStop, bool force)
517 /// Shut down the client view
518 /// </summary>
519 public void Close(bool sendStop)
520 { 528 {
521 // We lock here to prevent race conditions between two threads calling close simultaneously (e.g. 529 // We lock here to prevent race conditions between two threads calling close simultaneously (e.g.
522 // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection. 530 // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection.
523 lock (CloseSyncLock) 531 lock (CloseSyncLock)
524 { 532 {
525 if (!IsActive) 533 // We still perform a force close inside the sync lock since this is intended to attempt close where
534 // there is some unidentified connection problem, not where we have issues due to deadlock
535 if (!IsActive && !force)
526 return; 536 return;
527 537
528 IsActive = false; 538 IsActive = false;
@@ -837,8 +847,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
837 OutPacket(mov, ThrottleOutPacketType.Unknown); 847 OutPacket(mov, ThrottleOutPacketType.Unknown);
838 } 848 }
839 849
840 public void SendChatMessage(string message, byte type, Vector3 fromPos, string fromName, 850 public void SendChatMessage(
841 UUID fromAgentID, byte source, byte audible) 851 string message, byte type, Vector3 fromPos, string fromName,
852 UUID fromAgentID, UUID ownerID, byte source, byte audible)
842 { 853 {
843 ChatFromSimulatorPacket reply = (ChatFromSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.ChatFromSimulator); 854 ChatFromSimulatorPacket reply = (ChatFromSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.ChatFromSimulator);
844 reply.ChatData.Audible = audible; 855 reply.ChatData.Audible = audible;
@@ -847,7 +858,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
847 reply.ChatData.SourceType = source; 858 reply.ChatData.SourceType = source;
848 reply.ChatData.Position = fromPos; 859 reply.ChatData.Position = fromPos;
849 reply.ChatData.FromName = Util.StringToBytes256(fromName); 860 reply.ChatData.FromName = Util.StringToBytes256(fromName);
850 reply.ChatData.OwnerID = fromAgentID; 861 reply.ChatData.OwnerID = ownerID;
851 reply.ChatData.SourceID = fromAgentID; 862 reply.ChatData.SourceID = fromAgentID;
852 863
853 OutPacket(reply, ThrottleOutPacketType.Unknown); 864 OutPacket(reply, ThrottleOutPacketType.Unknown);
@@ -3985,7 +3996,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3985 { 3996 {
3986 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value; 3997 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3987 3998
3988 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3999 ImprovedTerseObjectUpdatePacket packet
4000 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
3989 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4001 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3990 packet.RegionData.TimeDilation = timeDilation; 4002 packet.RegionData.TimeDilation = timeDilation;
3991 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4003 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
@@ -4030,7 +4042,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4030 { 4042 {
4031 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 4043 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
4032 4044
4033 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 4045 ImprovedTerseObjectUpdatePacket packet
4046 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
4047 PacketType.ImprovedTerseObjectUpdate);
4034 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4048 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4035 packet.RegionData.TimeDilation = timeDilation; 4049 packet.RegionData.TimeDilation = timeDilation;
4036 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4050 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
@@ -4038,7 +4052,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4038 for (int i = 0; i < blocks.Count; i++) 4052 for (int i = 0; i < blocks.Count; i++)
4039 packet.ObjectData[i] = blocks[i]; 4053 packet.ObjectData[i] = blocks[i];
4040 4054
4041 OutPacket(packet, ThrottleOutPacketType.Task, true); 4055 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
4042 } 4056 }
4043 4057
4044 #endregion Packet Sending 4058 #endregion Packet Sending
@@ -4535,7 +4549,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4535 { 4549 {
4536 returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock(); 4550 returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock();
4537 } 4551 }
4538 j = 0; 4552 j = 0;
4539 4553
4540 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++; 4554 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
4541 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++; 4555 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++;
@@ -5039,7 +5053,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5039 Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Y, -64.0f, 64.0f), data, pos); pos += 2; 5053 Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Y, -64.0f, 64.0f), data, pos); pos += 2;
5040 Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Z, -64.0f, 64.0f), data, pos); pos += 2; 5054 Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Z, -64.0f, 64.0f), data, pos); pos += 2;
5041 5055
5042 ImprovedTerseObjectUpdatePacket.ObjectDataBlock block = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock(); 5056 ImprovedTerseObjectUpdatePacket.ObjectDataBlock block
5057 = PacketPool.Instance.GetDataBlock<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
5058
5043 block.Data = data; 5059 block.Data = data;
5044 5060
5045 if (textureEntry != null && textureEntry.Length > 0) 5061 if (textureEntry != null && textureEntry.Length > 0)
@@ -5289,14 +5305,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5289 protected virtual void RegisterLocalPacketHandlers() 5305 protected virtual void RegisterLocalPacketHandlers()
5290 { 5306 {
5291 AddLocalPacketHandler(PacketType.LogoutRequest, HandleLogout); 5307 AddLocalPacketHandler(PacketType.LogoutRequest, HandleLogout);
5308
5309 // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs
5310 // for each AgentUpdate packet.
5292 AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false); 5311 AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false);
5312
5293 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false); 5313 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false);
5294 AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false); 5314 AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false);
5295 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false); 5315 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false);
5296 AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false); 5316 AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false);
5297 AddLocalPacketHandler(PacketType.ParcelBuy, HandleParcelBuyRequest, false); 5317 AddLocalPacketHandler(PacketType.ParcelBuy, HandleParcelBuyRequest, false);
5298 AddLocalPacketHandler(PacketType.UUIDGroupNameRequest, HandleUUIDGroupNameRequest, false); 5318 AddLocalPacketHandler(PacketType.UUIDGroupNameRequest, HandleUUIDGroupNameRequest);
5299 AddLocalPacketHandler(PacketType.ObjectGroup, HandleObjectGroupRequest, false); 5319 AddLocalPacketHandler(PacketType.ObjectGroup, HandleObjectGroupRequest);
5300 AddLocalPacketHandler(PacketType.GenericMessage, HandleGenericMessage); 5320 AddLocalPacketHandler(PacketType.GenericMessage, HandleGenericMessage);
5301 AddLocalPacketHandler(PacketType.AvatarPropertiesRequest, HandleAvatarPropertiesRequest); 5321 AddLocalPacketHandler(PacketType.AvatarPropertiesRequest, HandleAvatarPropertiesRequest);
5302 AddLocalPacketHandler(PacketType.ChatFromViewer, HandleChatFromViewer); 5322 AddLocalPacketHandler(PacketType.ChatFromViewer, HandleChatFromViewer);
@@ -5396,9 +5416,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5396 AddLocalPacketHandler(PacketType.RemoveTaskInventory, HandleRemoveTaskInventory); 5416 AddLocalPacketHandler(PacketType.RemoveTaskInventory, HandleRemoveTaskInventory);
5397 AddLocalPacketHandler(PacketType.MoveTaskInventory, HandleMoveTaskInventory); 5417 AddLocalPacketHandler(PacketType.MoveTaskInventory, HandleMoveTaskInventory);
5398 AddLocalPacketHandler(PacketType.RezScript, HandleRezScript); 5418 AddLocalPacketHandler(PacketType.RezScript, HandleRezScript);
5399 AddLocalPacketHandler(PacketType.MapLayerRequest, HandleMapLayerRequest, false); 5419 AddLocalPacketHandler(PacketType.MapLayerRequest, HandleMapLayerRequest);
5400 AddLocalPacketHandler(PacketType.MapBlockRequest, HandleMapBlockRequest, false); 5420 AddLocalPacketHandler(PacketType.MapBlockRequest, HandleMapBlockRequest);
5401 AddLocalPacketHandler(PacketType.MapNameRequest, HandleMapNameRequest, false); 5421 AddLocalPacketHandler(PacketType.MapNameRequest, HandleMapNameRequest);
5402 AddLocalPacketHandler(PacketType.TeleportLandmarkRequest, HandleTeleportLandmarkRequest); 5422 AddLocalPacketHandler(PacketType.TeleportLandmarkRequest, HandleTeleportLandmarkRequest);
5403 AddLocalPacketHandler(PacketType.TeleportCancel, HandleTeleportCancel); 5423 AddLocalPacketHandler(PacketType.TeleportCancel, HandleTeleportCancel);
5404 AddLocalPacketHandler(PacketType.TeleportLocationRequest, HandleTeleportLocationRequest); 5424 AddLocalPacketHandler(PacketType.TeleportLocationRequest, HandleTeleportLocationRequest);
@@ -5518,81 +5538,84 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5518 5538
5519 #region Scene/Avatar 5539 #region Scene/Avatar
5520 5540
5521 private bool HandleAgentUpdate(IClientAPI sener, Packet Pack) 5541 private bool HandleAgentUpdate(IClientAPI sener, Packet packet)
5522 { 5542 {
5523 if (OnAgentUpdate != null) 5543 if (OnAgentUpdate != null)
5524 { 5544 {
5525 bool update = false; 5545 AgentUpdatePacket agentUpdate = (AgentUpdatePacket)packet;
5526 AgentUpdatePacket agenUpdate = (AgentUpdatePacket)Pack;
5527 5546
5528 #region Packet Session and User Check 5547 #region Packet Session and User Check
5529 if (agenUpdate.AgentData.SessionID != SessionId || agenUpdate.AgentData.AgentID != AgentId) 5548 if (agentUpdate.AgentData.SessionID != SessionId || agentUpdate.AgentData.AgentID != AgentId)
5549 {
5550 PacketPool.Instance.ReturnPacket(packet);
5530 return false; 5551 return false;
5552 }
5531 #endregion 5553 #endregion
5532 5554
5533 AgentUpdatePacket.AgentDataBlock x = agenUpdate.AgentData; 5555 bool update = false;
5534 5556 AgentUpdatePacket.AgentDataBlock x = agentUpdate.AgentData;
5535 // We can only check when we have something to check
5536 // against.
5537 5557
5538 if (lastarg != null) 5558 if (m_lastAgentUpdateArgs != null)
5539 { 5559 {
5560 // These should be ordered from most-likely to
5561 // least likely to change. I've made an initial
5562 // guess at that.
5540 update = 5563 update =
5541 ( 5564 (
5542 (x.BodyRotation != lastarg.BodyRotation) || 5565 (x.BodyRotation != m_lastAgentUpdateArgs.BodyRotation) ||
5543 (x.CameraAtAxis != lastarg.CameraAtAxis) || 5566 (x.CameraAtAxis != m_lastAgentUpdateArgs.CameraAtAxis) ||
5544 (x.CameraCenter != lastarg.CameraCenter) || 5567 (x.CameraCenter != m_lastAgentUpdateArgs.CameraCenter) ||
5545 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5568 (x.CameraLeftAxis != m_lastAgentUpdateArgs.CameraLeftAxis) ||
5546 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5569 (x.CameraUpAxis != m_lastAgentUpdateArgs.CameraUpAxis) ||
5547 (x.ControlFlags != lastarg.ControlFlags) || 5570 (x.ControlFlags != m_lastAgentUpdateArgs.ControlFlags) ||
5548 (x.ControlFlags != 0) || 5571 (x.ControlFlags != 0) ||
5549 (x.Far != lastarg.Far) || 5572 (x.Far != m_lastAgentUpdateArgs.Far) ||
5550 (x.Flags != lastarg.Flags) || 5573 (x.Flags != m_lastAgentUpdateArgs.Flags) ||
5551 (x.State != lastarg.State) || 5574 (x.State != m_lastAgentUpdateArgs.State) ||
5552 (x.HeadRotation != lastarg.HeadRotation) || 5575 (x.HeadRotation != m_lastAgentUpdateArgs.HeadRotation) ||
5553 (x.SessionID != lastarg.SessionID) || 5576 (x.SessionID != m_lastAgentUpdateArgs.SessionID) ||
5554 (x.AgentID != lastarg.AgentID) 5577 (x.AgentID != m_lastAgentUpdateArgs.AgentID)
5555 ); 5578 );
5556 } 5579 }
5557 else 5580 else
5558 { 5581 {
5582 m_lastAgentUpdateArgs = new AgentUpdateArgs();
5559 update = true; 5583 update = true;
5560 } 5584 }
5561 5585
5562 // These should be ordered from most-likely to
5563 // least likely to change. I've made an initial
5564 // guess at that.
5565
5566 if (update) 5586 if (update)
5567 { 5587 {
5568// m_log.DebugFormat("[LLCLIENTVIEW]: Triggered AgentUpdate for {0}", sener.Name); 5588// m_log.DebugFormat("[LLCLIENTVIEW]: Triggered AgentUpdate for {0}", sener.Name);
5569 5589
5570 AgentUpdateArgs arg = new AgentUpdateArgs(); 5590 m_lastAgentUpdateArgs.AgentID = x.AgentID;
5571 arg.AgentID = x.AgentID; 5591 m_lastAgentUpdateArgs.BodyRotation = x.BodyRotation;
5572 arg.BodyRotation = x.BodyRotation; 5592 m_lastAgentUpdateArgs.CameraAtAxis = x.CameraAtAxis;
5573 arg.CameraAtAxis = x.CameraAtAxis; 5593 m_lastAgentUpdateArgs.CameraCenter = x.CameraCenter;
5574 arg.CameraCenter = x.CameraCenter; 5594 m_lastAgentUpdateArgs.CameraLeftAxis = x.CameraLeftAxis;
5575 arg.CameraLeftAxis = x.CameraLeftAxis; 5595 m_lastAgentUpdateArgs.CameraUpAxis = x.CameraUpAxis;
5576 arg.CameraUpAxis = x.CameraUpAxis; 5596 m_lastAgentUpdateArgs.ControlFlags = x.ControlFlags;
5577 arg.ControlFlags = x.ControlFlags; 5597 m_lastAgentUpdateArgs.Far = x.Far;
5578 arg.Far = x.Far; 5598 m_lastAgentUpdateArgs.Flags = x.Flags;
5579 arg.Flags = x.Flags; 5599 m_lastAgentUpdateArgs.HeadRotation = x.HeadRotation;
5580 arg.HeadRotation = x.HeadRotation; 5600 m_lastAgentUpdateArgs.SessionID = x.SessionID;
5581 arg.SessionID = x.SessionID; 5601 m_lastAgentUpdateArgs.State = x.State;
5582 arg.State = x.State; 5602
5583 UpdateAgent handlerAgentUpdate = OnAgentUpdate; 5603 UpdateAgent handlerAgentUpdate = OnAgentUpdate;
5584 UpdateAgent handlerPreAgentUpdate = OnPreAgentUpdate; 5604 UpdateAgent handlerPreAgentUpdate = OnPreAgentUpdate;
5585 lastarg = arg; // save this set of arguments for nexttime 5605
5586 if (handlerPreAgentUpdate != null) 5606 if (handlerPreAgentUpdate != null)
5587 OnPreAgentUpdate(this, arg); 5607 OnPreAgentUpdate(this, m_lastAgentUpdateArgs);
5608
5588 if (handlerAgentUpdate != null) 5609 if (handlerAgentUpdate != null)
5589 OnAgentUpdate(this, arg); 5610 OnAgentUpdate(this, m_lastAgentUpdateArgs);
5590 5611
5591 handlerAgentUpdate = null; 5612 handlerAgentUpdate = null;
5592 handlerPreAgentUpdate = null; 5613 handlerPreAgentUpdate = null;
5593 } 5614 }
5594 } 5615 }
5595 5616
5617 PacketPool.Instance.ReturnPacket(packet);
5618
5596 return true; 5619 return true;
5597 } 5620 }
5598 5621
@@ -5964,7 +5987,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5964 msgpack.MessageBlock.ID, 5987 msgpack.MessageBlock.ID,
5965 msgpack.MessageBlock.Offline != 0 ? true : false, 5988 msgpack.MessageBlock.Offline != 0 ? true : false,
5966 msgpack.MessageBlock.Position, 5989 msgpack.MessageBlock.Position,
5967 msgpack.MessageBlock.BinaryBucket); 5990 msgpack.MessageBlock.BinaryBucket,
5991 true);
5968 5992
5969 handlerInstantMessage(this, im); 5993 handlerInstantMessage(this, im);
5970 } 5994 }
@@ -9251,7 +9275,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9251 } 9275 }
9252 #endregion 9276 #endregion
9253 9277
9254 switch (Utils.BytesToString(messagePacket.MethodData.Method)) 9278 string method = Utils.BytesToString(messagePacket.MethodData.Method);
9279
9280 switch (method)
9255 { 9281 {
9256 case "getinfo": 9282 case "getinfo":
9257 if (((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false)) 9283 if (((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false))
@@ -9567,7 +9593,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9567 return true; 9593 return true;
9568 9594
9569 default: 9595 default:
9570 m_log.Error("EstateOwnerMessage: Unknown method requested\n" + messagePacket); 9596 m_log.WarnFormat(
9597 "[LLCLIENTVIEW]: EstateOwnerMessage: Unknown method {0} requested for {1} in {2}",
9598 method, Name, Scene.Name);
9599
9600 for (int i = 0; i < messagePacket.ParamList.Length; i++)
9601 {
9602 EstateOwnerMessagePacket.ParamListBlock block = messagePacket.ParamList[i];
9603 string data = (string)Utils.BytesToString(block.Parameter);
9604 m_log.DebugFormat("[LLCLIENTVIEW]: Param {0}={1}", i, data);
9605 }
9606
9571 return true; 9607 return true;
9572 } 9608 }
9573 9609
@@ -11960,7 +11996,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11960 logPacket = false; 11996 logPacket = false;
11961 11997
11962 if (DebugPacketLevel <= 50 11998 if (DebugPacketLevel <= 50
11963 & (packet.Type == PacketType.ImprovedTerseObjectUpdate || packet.Type == PacketType.ObjectUpdate)) 11999 && (packet.Type == PacketType.ImprovedTerseObjectUpdate || packet.Type == PacketType.ObjectUpdate))
11964 logPacket = false; 12000 logPacket = false;
11965 12001
11966 if (DebugPacketLevel <= 25 && packet.Type == PacketType.ObjectPropertiesFamily) 12002 if (DebugPacketLevel <= 25 && packet.Type == PacketType.ObjectPropertiesFamily)
@@ -12034,8 +12070,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12034 12070
12035 if (!ProcessPacketMethod(packet)) 12071 if (!ProcessPacketMethod(packet))
12036 m_log.Warn("[CLIENT]: unhandled packet " + packet.Type); 12072 m_log.Warn("[CLIENT]: unhandled packet " + packet.Type);
12037
12038 PacketPool.Instance.ReturnPacket(packet);
12039 } 12073 }
12040 12074
12041 private static PrimitiveBaseShape GetShapeFromAddPacket(ObjectAddPacket addPacket) 12075 private static PrimitiveBaseShape GetShapeFromAddPacket(ObjectAddPacket addPacket)
@@ -12204,7 +12238,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12204 { 12238 {
12205 Kick(reason); 12239 Kick(reason);
12206 Thread.Sleep(1000); 12240 Thread.Sleep(1000);
12207 Close(); 12241 Disconnect();
12208 } 12242 }
12209 12243
12210 public void Disconnect() 12244 public void Disconnect()
@@ -12492,7 +12526,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12492 ushort timeDilation = Utils.FloatToUInt16(TIME_DILATION, 0.0f, 1.0f); 12526 ushort timeDilation = Utils.FloatToUInt16(TIME_DILATION, 0.0f, 1.0f);
12493 12527
12494 12528
12495 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 12529 ImprovedTerseObjectUpdatePacket packet
12530 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
12531 PacketType.ImprovedTerseObjectUpdate);
12532
12496 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 12533 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
12497 packet.RegionData.TimeDilation = timeDilation; 12534 packet.RegionData.TimeDilation = timeDilation;
12498 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1]; 12535 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index d6513c5..9a4abd4 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -37,6 +37,7 @@ using log4net;
37using Nini.Config; 37using Nini.Config;
38using OpenMetaverse.Packets; 38using OpenMetaverse.Packets;
39using OpenSim.Framework; 39using OpenSim.Framework;
40using OpenSim.Framework.Console;
40using OpenSim.Framework.Monitoring; 41using OpenSim.Framework.Monitoring;
41using OpenSim.Region.Framework.Scenes; 42using OpenSim.Region.Framework.Scenes;
42using OpenMetaverse; 43using OpenMetaverse;
@@ -69,6 +70,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
69 public void AddScene(IScene scene) 70 public void AddScene(IScene scene)
70 { 71 {
71 m_udpServer.AddScene(scene); 72 m_udpServer.AddScene(scene);
73
74 StatsManager.RegisterStat(
75 new Stat(
76 "IncomingPacketsProcessedCount",
77 "Number of inbound UDP packets processed",
78 "Number of inbound UDP packets processed",
79 "",
80 "clientstack",
81 scene.Name,
82 StatType.Pull,
83 MeasuresOfInterest.AverageChangeOverTime,
84 stat => stat.Value = m_udpServer.IncomingPacketsProcessed,
85 StatVerbosity.Debug));
72 } 86 }
73 87
74 public bool HandlesRegion(Location x) 88 public bool HandlesRegion(Location x)
@@ -100,9 +114,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
100 114
101 /// <summary>The measured resolution of Environment.TickCount</summary> 115 /// <summary>The measured resolution of Environment.TickCount</summary>
102 public readonly float TickCountResolution; 116 public readonly float TickCountResolution;
117
103 /// <summary>Number of prim updates to put on the queue each time the 118 /// <summary>Number of prim updates to put on the queue each time the
104 /// OnQueueEmpty event is triggered for updates</summary> 119 /// OnQueueEmpty event is triggered for updates</summary>
105 public readonly int PrimUpdatesPerCallback; 120 public readonly int PrimUpdatesPerCallback;
121
106 /// <summary>Number of texture packets to put on the queue each time the 122 /// <summary>Number of texture packets to put on the queue each time the
107 /// OnQueueEmpty event is triggered for textures</summary> 123 /// OnQueueEmpty event is triggered for textures</summary>
108 public readonly int TextureSendLimit; 124 public readonly int TextureSendLimit;
@@ -124,28 +140,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP
124 140
125 /// <summary>Manages authentication for agent circuits</summary> 141 /// <summary>Manages authentication for agent circuits</summary>
126 private AgentCircuitManager m_circuitManager; 142 private AgentCircuitManager m_circuitManager;
143
127 /// <summary>Reference to the scene this UDP server is attached to</summary> 144 /// <summary>Reference to the scene this UDP server is attached to</summary>
128 protected Scene m_scene; 145 protected Scene m_scene;
146
129 /// <summary>The X/Y coordinates of the scene this UDP server is attached to</summary> 147 /// <summary>The X/Y coordinates of the scene this UDP server is attached to</summary>
130 private Location m_location; 148 private Location m_location;
149
131 /// <summary>The size of the receive buffer for the UDP socket. This value 150 /// <summary>The size of the receive buffer for the UDP socket. This value
132 /// is passed up to the operating system and used in the system networking 151 /// is passed up to the operating system and used in the system networking
133 /// stack. Use zero to leave this value as the default</summary> 152 /// stack. Use zero to leave this value as the default</summary>
134 private int m_recvBufferSize; 153 private int m_recvBufferSize;
154
135 /// <summary>Flag to process packets asynchronously or synchronously</summary> 155 /// <summary>Flag to process packets asynchronously or synchronously</summary>
136 private bool m_asyncPacketHandling; 156 private bool m_asyncPacketHandling;
157
137 /// <summary>Tracks whether or not a packet was sent each round so we know 158 /// <summary>Tracks whether or not a packet was sent each round so we know
138 /// whether or not to sleep</summary> 159 /// whether or not to sleep</summary>
139 private bool m_packetSent; 160 private bool m_packetSent;
140 161
141 /// <summary>Environment.TickCount of the last time that packet stats were reported to the scene</summary> 162 /// <summary>Environment.TickCount of the last time that packet stats were reported to the scene</summary>
142 private int m_elapsedMSSinceLastStatReport = 0; 163 private int m_elapsedMSSinceLastStatReport = 0;
164
143 /// <summary>Environment.TickCount of the last time the outgoing packet handler executed</summary> 165 /// <summary>Environment.TickCount of the last time the outgoing packet handler executed</summary>
144 private int m_tickLastOutgoingPacketHandler; 166 private int m_tickLastOutgoingPacketHandler;
167
145 /// <summary>Keeps track of the number of elapsed milliseconds since the last time the outgoing packet handler looped</summary> 168 /// <summary>Keeps track of the number of elapsed milliseconds since the last time the outgoing packet handler looped</summary>
146 private int m_elapsedMSOutgoingPacketHandler; 169 private int m_elapsedMSOutgoingPacketHandler;
170
147 /// <summary>Keeps track of the number of 100 millisecond periods elapsed in the outgoing packet handler executed</summary> 171 /// <summary>Keeps track of the number of 100 millisecond periods elapsed in the outgoing packet handler executed</summary>
148 private int m_elapsed100MSOutgoingPacketHandler; 172 private int m_elapsed100MSOutgoingPacketHandler;
173
149 /// <summary>Keeps track of the number of 500 millisecond periods elapsed in the outgoing packet handler executed</summary> 174 /// <summary>Keeps track of the number of 500 millisecond periods elapsed in the outgoing packet handler executed</summary>
150 private int m_elapsed500MSOutgoingPacketHandler; 175 private int m_elapsed500MSOutgoingPacketHandler;
151 176
@@ -159,6 +184,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
159 protected bool m_sendPing; 184 protected bool m_sendPing;
160 185
161 private ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>(); 186 private ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>();
187 private Pool<IncomingPacket> m_incomingPacketPool;
188
189 /// <summary>
190 /// Stat for number of packets in the main pool awaiting use.
191 /// </summary>
192 private Stat m_poolCountStat;
193
194 /// <summary>
195 /// Stat for number of packets in the inbound packet pool awaiting use.
196 /// </summary>
197 private Stat m_incomingPacketPoolStat;
162 198
163 private int m_defaultRTO = 0; 199 private int m_defaultRTO = 0;
164 private int m_maxRTO = 0; 200 private int m_maxRTO = 0;
@@ -180,7 +216,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
180 /// </summary> 216 /// </summary>
181 private IClientAPI m_currentIncomingClient; 217 private IClientAPI m_currentIncomingClient;
182 218
183 public LLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager) 219 public LLUDPServer(
220 IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port,
221 IConfigSource configSource, AgentCircuitManager circuitManager)
184 : base(listenIP, (int)port) 222 : base(listenIP, (int)port)
185 { 223 {
186 #region Environment.TickCount Measurement 224 #region Environment.TickCount Measurement
@@ -202,6 +240,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
202 240
203 m_circuitManager = circuitManager; 241 m_circuitManager = circuitManager;
204 int sceneThrottleBps = 0; 242 int sceneThrottleBps = 0;
243 bool usePools = false;
205 244
206 IConfig config = configSource.Configs["ClientStack.LindenUDP"]; 245 IConfig config = configSource.Configs["ClientStack.LindenUDP"];
207 if (config != null) 246 if (config != null)
@@ -227,6 +266,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
227 m_pausedAckTimeout = 1000 * 300; // 5 minutes 266 m_pausedAckTimeout = 1000 * 300; // 5 minutes
228 } 267 }
229 268
269 // FIXME: This actually only needs to be done once since the PacketPool is shared across all servers.
270 // However, there is no harm in temporarily doing it multiple times.
271 IConfig packetConfig = configSource.Configs["PacketPool"];
272 if (packetConfig != null)
273 {
274 PacketPool.Instance.RecyclePackets = packetConfig.GetBoolean("RecyclePackets", true);
275 PacketPool.Instance.RecycleDataBlocks = packetConfig.GetBoolean("RecycleDataBlocks", true);
276 usePools = packetConfig.GetBoolean("RecycleBaseUDPPackets", usePools);
277 }
278
230 #region BinaryStats 279 #region BinaryStats
231 config = configSource.Configs["Statistics.Binary"]; 280 config = configSource.Configs["Statistics.Binary"];
232 m_shouldCollectStats = false; 281 m_shouldCollectStats = false;
@@ -254,20 +303,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
254 303
255 m_throttle = new TokenBucket(null, sceneThrottleBps); 304 m_throttle = new TokenBucket(null, sceneThrottleBps);
256 ThrottleRates = new ThrottleRates(configSource); 305 ThrottleRates = new ThrottleRates(configSource);
306
307 if (usePools)
308 EnablePools();
257 } 309 }
258 310
259 public void Start() 311 public void Start()
260 { 312 {
261 if (m_scene == null) 313 StartInbound();
262 throw new InvalidOperationException("[LLUDPSERVER]: Cannot LLUDPServer.Start() without an IScene reference"); 314 StartOutbound();
315
316 m_elapsedMSSinceLastStatReport = Environment.TickCount;
317 }
263 318
319 private void StartInbound()
320 {
264 m_log.InfoFormat( 321 m_log.InfoFormat(
265 "[LLUDPSERVER]: Starting the LLUDP server in {0} mode", 322 "[LLUDPSERVER]: Starting inbound packet processing for the LLUDP server in {0} mode with UsePools = {1}",
266 m_asyncPacketHandling ? "asynchronous" : "synchronous"); 323 m_asyncPacketHandling ? "asynchronous" : "synchronous", UsePools);
267 324
268 base.Start(m_recvBufferSize, m_asyncPacketHandling); 325 base.StartInbound(m_recvBufferSize, m_asyncPacketHandling);
269 326
270 // Start the packet processing threads 327 // This thread will process the packets received that are placed on the packetInbox
271 Watchdog.StartThread( 328 Watchdog.StartThread(
272 IncomingPacketHandler, 329 IncomingPacketHandler,
273 string.Format("Incoming Packets ({0})", m_scene.RegionInfo.RegionName), 330 string.Format("Incoming Packets ({0})", m_scene.RegionInfo.RegionName),
@@ -276,6 +333,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
276 true, 333 true,
277 GetWatchdogIncomingAlarmData, 334 GetWatchdogIncomingAlarmData,
278 Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS); 335 Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS);
336 }
337
338 private new void StartOutbound()
339 {
340 m_log.Info("[LLUDPSERVER]: Starting outbound packet processing for the LLUDP server");
341
342 base.StartOutbound();
279 343
280 Watchdog.StartThread( 344 Watchdog.StartThread(
281 OutgoingPacketHandler, 345 OutgoingPacketHandler,
@@ -285,8 +349,90 @@ namespace OpenSim.Region.ClientStack.LindenUDP
285 true, 349 true,
286 GetWatchdogOutgoingAlarmData, 350 GetWatchdogOutgoingAlarmData,
287 Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS); 351 Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS);
352 }
288 353
289 m_elapsedMSSinceLastStatReport = Environment.TickCount; 354 public void Stop()
355 {
356 m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + m_scene.RegionInfo.RegionName);
357 base.StopOutbound();
358 base.StopInbound();
359 }
360
361 protected override bool EnablePools()
362 {
363 if (!UsePools)
364 {
365 base.EnablePools();
366
367 m_incomingPacketPool = new Pool<IncomingPacket>(() => new IncomingPacket(), 500);
368
369 return true;
370 }
371
372 return false;
373 }
374
375 protected override bool DisablePools()
376 {
377 if (UsePools)
378 {
379 base.DisablePools();
380
381 StatsManager.DeregisterStat(m_incomingPacketPoolStat);
382
383 // We won't null out the pool to avoid a race condition with code that may be in the middle of using it.
384
385 return true;
386 }
387
388 return false;
389 }
390
391 /// <summary>
392 /// This is a seperate method so that it can be called once we have an m_scene to distinguish different scene
393 /// stats.
394 /// </summary>
395 private void EnablePoolStats()
396 {
397 m_poolCountStat
398 = new Stat(
399 "UDPPacketBufferPoolCount",
400 "Objects within the UDPPacketBuffer pool",
401 "The number of objects currently stored within the UDPPacketBuffer pool",
402 "",
403 "clientstack",
404 m_scene.Name,
405 StatType.Pull,
406 stat => stat.Value = Pool.Count,
407 StatVerbosity.Debug);
408
409 StatsManager.RegisterStat(m_poolCountStat);
410
411 m_incomingPacketPoolStat
412 = new Stat(
413 "IncomingPacketPoolCount",
414 "Objects within incoming packet pool",
415 "The number of objects currently stored within the incoming packet pool",
416 "",
417 "clientstack",
418 m_scene.Name,
419 StatType.Pull,
420 stat => stat.Value = m_incomingPacketPool.Count,
421 StatVerbosity.Debug);
422
423 StatsManager.RegisterStat(m_incomingPacketPoolStat);
424 }
425
426 /// <summary>
427 /// Disables pool stats.
428 /// </summary>
429 private void DisablePoolStats()
430 {
431 StatsManager.DeregisterStat(m_poolCountStat);
432 m_poolCountStat = null;
433
434 StatsManager.DeregisterStat(m_incomingPacketPoolStat);
435 m_incomingPacketPoolStat = null;
290 } 436 }
291 437
292 /// <summary> 438 /// <summary>
@@ -311,12 +457,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
311 m_currentOutgoingClient != null ? m_currentOutgoingClient.Name : "none"); 457 m_currentOutgoingClient != null ? m_currentOutgoingClient.Name : "none");
312 } 458 }
313 459
314 public new void Stop()
315 {
316 m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + m_scene.RegionInfo.RegionName);
317 base.Stop();
318 }
319
320 public void AddScene(IScene scene) 460 public void AddScene(IScene scene)
321 { 461 {
322 if (m_scene != null) 462 if (m_scene != null)
@@ -333,6 +473,182 @@ namespace OpenSim.Region.ClientStack.LindenUDP
333 473
334 m_scene = (Scene)scene; 474 m_scene = (Scene)scene;
335 m_location = new Location(m_scene.RegionInfo.RegionHandle); 475 m_location = new Location(m_scene.RegionInfo.RegionHandle);
476
477 // XXX: These stats are also pool stats but we register them separately since they are currently not
478 // turned on and off by EnablePools()/DisablePools()
479 StatsManager.RegisterStat(
480 new PercentageStat(
481 "PacketsReused",
482 "Packets reused",
483 "Number of packets reused out of all requests to the packet pool",
484 "clientstack",
485 m_scene.Name,
486 StatType.Pull,
487 stat =>
488 { PercentageStat pstat = (PercentageStat)stat;
489 pstat.Consequent = PacketPool.Instance.PacketsRequested;
490 pstat.Antecedent = PacketPool.Instance.PacketsReused; },
491 StatVerbosity.Debug));
492
493 StatsManager.RegisterStat(
494 new PercentageStat(
495 "PacketDataBlocksReused",
496 "Packet data blocks reused",
497 "Number of data blocks reused out of all requests to the packet pool",
498 "clientstack",
499 m_scene.Name,
500 StatType.Pull,
501 stat =>
502 { PercentageStat pstat = (PercentageStat)stat;
503 pstat.Consequent = PacketPool.Instance.BlocksRequested;
504 pstat.Antecedent = PacketPool.Instance.BlocksReused; },
505 StatVerbosity.Debug));
506
507 StatsManager.RegisterStat(
508 new Stat(
509 "PacketsPoolCount",
510 "Objects within the packet pool",
511 "The number of objects currently stored within the packet pool",
512 "",
513 "clientstack",
514 m_scene.Name,
515 StatType.Pull,
516 stat => stat.Value = PacketPool.Instance.PacketsPooled,
517 StatVerbosity.Debug));
518
519 StatsManager.RegisterStat(
520 new Stat(
521 "PacketDataBlocksPoolCount",
522 "Objects within the packet data block pool",
523 "The number of objects currently stored within the packet data block pool",
524 "",
525 "clientstack",
526 m_scene.Name,
527 StatType.Pull,
528 stat => stat.Value = PacketPool.Instance.BlocksPooled,
529 StatVerbosity.Debug));
530
531 // We delay enabling pool stats to AddScene() instead of Initialize() so that we can distinguish pool stats by
532 // scene name
533 if (UsePools)
534 EnablePoolStats();
535
536 MainConsole.Instance.Commands.AddCommand(
537 "Debug",
538 false,
539 "debug lludp start",
540 "debug lludp start <in|out|all>",
541 "Control LLUDP packet processing.",
542 "No effect if packet processing has already started.\n"
543 + "in - start inbound processing.\n"
544 + "out - start outbound processing.\n"
545 + "all - start in and outbound processing.\n",
546 HandleStartCommand);
547
548 MainConsole.Instance.Commands.AddCommand(
549 "Debug",
550 false,
551 "debug lludp stop",
552 "debug lludp stop <in|out|all>",
553 "Stop LLUDP packet processing.",
554 "No effect if packet processing has already stopped.\n"
555 + "in - stop inbound processing.\n"
556 + "out - stop outbound processing.\n"
557 + "all - stop in and outbound processing.\n",
558 HandleStopCommand);
559
560 MainConsole.Instance.Commands.AddCommand(
561 "Debug",
562 false,
563 "debug lludp pool",
564 "debug lludp pool <on|off>",
565 "Turn object pooling within the lludp component on or off.",
566 HandlePoolCommand);
567
568 MainConsole.Instance.Commands.AddCommand(
569 "Debug",
570 false,
571 "debug lludp status",
572 "debug lludp status",
573 "Return status of LLUDP packet processing.",
574 HandleStatusCommand);
575 }
576
577 private void HandleStartCommand(string module, string[] args)
578 {
579 if (args.Length != 4)
580 {
581 MainConsole.Instance.Output("Usage: debug lludp start <in|out|all>");
582 return;
583 }
584
585 string subCommand = args[3];
586
587 if (subCommand == "in" || subCommand == "all")
588 StartInbound();
589
590 if (subCommand == "out" || subCommand == "all")
591 StartOutbound();
592 }
593
594 private void HandleStopCommand(string module, string[] args)
595 {
596 if (args.Length != 4)
597 {
598 MainConsole.Instance.Output("Usage: debug lludp stop <in|out|all>");
599 return;
600 }
601
602 string subCommand = args[3];
603
604 if (subCommand == "in" || subCommand == "all")
605 StopInbound();
606
607 if (subCommand == "out" || subCommand == "all")
608 StopOutbound();
609 }
610
611 private void HandlePoolCommand(string module, string[] args)
612 {
613 if (args.Length != 4)
614 {
615 MainConsole.Instance.Output("Usage: debug lludp pool <on|off>");
616 return;
617 }
618
619 string enabled = args[3];
620
621 if (enabled == "on")
622 {
623 if (EnablePools())
624 {
625 EnablePoolStats();
626 MainConsole.Instance.OutputFormat("Packet pools enabled on {0}", m_scene.Name);
627 }
628 }
629 else if (enabled == "off")
630 {
631 if (DisablePools())
632 {
633 DisablePoolStats();
634 MainConsole.Instance.OutputFormat("Packet pools disabled on {0}", m_scene.Name);
635 }
636 }
637 else
638 {
639 MainConsole.Instance.Output("Usage: debug lludp pool <on|off>");
640 }
641 }
642
643 private void HandleStatusCommand(string module, string[] args)
644 {
645 MainConsole.Instance.OutputFormat(
646 "IN LLUDP packet processing for {0} is {1}", m_scene.Name, IsRunningInbound ? "enabled" : "disabled");
647
648 MainConsole.Instance.OutputFormat(
649 "OUT LLUDP packet processing for {0} is {1}", m_scene.Name, IsRunningOutbound ? "enabled" : "disabled");
650
651 MainConsole.Instance.OutputFormat("LLUDP pools in {0} are {1}", m_scene.Name, UsePools ? "on" : "off");
336 } 652 }
337 653
338 public bool HandlesRegion(Location x) 654 public bool HandlesRegion(Location x)
@@ -416,6 +732,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
416 byte[] data = packet.ToBytes(); 732 byte[] data = packet.ToBytes();
417 SendPacketData(udpClient, data, packet.Type, category, method); 733 SendPacketData(udpClient, data, packet.Type, category, method);
418 } 734 }
735
736 PacketPool.Instance.ReturnPacket(packet);
419 } 737 }
420 738
421 /// <summary> 739 /// <summary>
@@ -700,7 +1018,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
700 LLUDPClient udpClient = null; 1018 LLUDPClient udpClient = null;
701 Packet packet = null; 1019 Packet packet = null;
702 int packetEnd = buffer.DataLength - 1; 1020 int packetEnd = buffer.DataLength - 1;
703 IPEndPoint address = (IPEndPoint)buffer.RemoteEndPoint; 1021 IPEndPoint endPoint = (IPEndPoint)buffer.RemoteEndPoint;
704 1022
705 #region Decoding 1023 #region Decoding
706 1024
@@ -710,7 +1028,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
710// "[LLUDPSERVER]: Dropping undersized packet with {0} bytes received from {1} in {2}", 1028// "[LLUDPSERVER]: Dropping undersized packet with {0} bytes received from {1} in {2}",
711// buffer.DataLength, buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName); 1029// buffer.DataLength, buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
712 1030
713 return; // Drop undersizd packet 1031 return; // Drop undersized packet
714 } 1032 }
715 1033
716 int headerLen = 7; 1034 int headerLen = 7;
@@ -733,7 +1051,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
733 1051
734 try 1052 try
735 { 1053 {
736 packet = Packet.BuildPacket(buffer.Data, ref packetEnd, 1054// packet = Packet.BuildPacket(buffer.Data, ref packetEnd,
1055// // Only allocate a buffer for zerodecoding if the packet is zerocoded
1056// ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null);
1057 // If OpenSimUDPBase.UsePool == true (which is currently separate from the PacketPool) then we
1058 // assume that packet construction does not retain a reference to byte[] buffer.Data (instead, all
1059 // bytes are copied out).
1060 packet = PacketPool.Instance.GetPacket(buffer.Data, ref packetEnd,
737 // Only allocate a buffer for zerodecoding if the packet is zerocoded 1061 // Only allocate a buffer for zerodecoding if the packet is zerocoded
738 ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null); 1062 ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null);
739 } 1063 }
@@ -748,11 +1072,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
748 1072
749 return; // Drop short packet 1073 return; // Drop short packet
750 } 1074 }
751 catch(Exception e) 1075 catch (Exception e)
752 { 1076 {
753 if (m_malformedCount < 100) 1077 if (m_malformedCount < 100)
754 m_log.DebugFormat("[LLUDPSERVER]: Dropped malformed packet: " + e.ToString()); 1078 m_log.DebugFormat("[LLUDPSERVER]: Dropped malformed packet: " + e.ToString());
1079
755 m_malformedCount++; 1080 m_malformedCount++;
1081
756 if ((m_malformedCount % 100000) == 0) 1082 if ((m_malformedCount % 100000) == 0)
757 m_log.DebugFormat("[LLUDPSERVER]: Received {0} malformed packets so far, probable network attack.", m_malformedCount); 1083 m_log.DebugFormat("[LLUDPSERVER]: Received {0} malformed packets so far, probable network attack.", m_malformedCount);
758 } 1084 }
@@ -772,7 +1098,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
772 1098
773 // If there is already a client for this endpoint, don't process UseCircuitCode 1099 // If there is already a client for this endpoint, don't process UseCircuitCode
774 IClientAPI client = null; 1100 IClientAPI client = null;
775 if (!m_scene.TryGetClient(address, out client)) 1101 if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
776 { 1102 {
777 // UseCircuitCode handling 1103 // UseCircuitCode handling
778 if (packet.Type == PacketType.UseCircuitCode) 1104 if (packet.Type == PacketType.UseCircuitCode)
@@ -780,13 +1106,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
780 // And if there is a UseCircuitCode pending, also drop it 1106 // And if there is a UseCircuitCode pending, also drop it
781 lock (m_pendingCache) 1107 lock (m_pendingCache)
782 { 1108 {
783 if (m_pendingCache.Contains(address)) 1109 if (m_pendingCache.Contains(endPoint))
784 return; 1110 return;
785 1111
786 m_pendingCache.AddOrUpdate(address, new Queue<UDPPacketBuffer>(), 60); 1112 m_pendingCache.AddOrUpdate(endPoint, new Queue<UDPPacketBuffer>(), 60);
787 } 1113 }
788 1114
789 object[] array = new object[] { buffer, packet }; 1115 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the
1116 // buffer.
1117 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
790 1118
791 Util.FireAndForget(HandleUseCircuitCode, array); 1119 Util.FireAndForget(HandleUseCircuitCode, array);
792 1120
@@ -798,7 +1126,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
798 lock (m_pendingCache) 1126 lock (m_pendingCache)
799 { 1127 {
800 Queue<UDPPacketBuffer> queue; 1128 Queue<UDPPacketBuffer> queue;
801 if (m_pendingCache.TryGetValue(address, out queue)) 1129 if (m_pendingCache.TryGetValue(endPoint, out queue))
802 { 1130 {
803 //m_log.DebugFormat("[LLUDPSERVER]: Enqueued a {0} packet into the pending queue", packet.Type); 1131 //m_log.DebugFormat("[LLUDPSERVER]: Enqueued a {0} packet into the pending queue", packet.Type);
804 queue.Enqueue(buffer); 1132 queue.Enqueue(buffer);
@@ -834,6 +1162,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
834 // Handle appended ACKs 1162 // Handle appended ACKs
835 if (packet.Header.AppendedAcks && packet.Header.AckList != null) 1163 if (packet.Header.AppendedAcks && packet.Header.AckList != null)
836 { 1164 {
1165// m_log.DebugFormat(
1166// "[LLUDPSERVER]: Handling {0} appended acks from {1} in {2}",
1167// packet.Header.AckList.Length, client.Name, m_scene.Name);
1168
837 for (int i = 0; i < packet.Header.AckList.Length; i++) 1169 for (int i = 0; i < packet.Header.AckList.Length; i++)
838 udpClient.NeedAcks.Acknowledge(packet.Header.AckList[i], now, packet.Header.Resent); 1170 udpClient.NeedAcks.Acknowledge(packet.Header.AckList[i], now, packet.Header.Resent);
839 } 1171 }
@@ -843,6 +1175,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
843 { 1175 {
844 PacketAckPacket ackPacket = (PacketAckPacket)packet; 1176 PacketAckPacket ackPacket = (PacketAckPacket)packet;
845 1177
1178// m_log.DebugFormat(
1179// "[LLUDPSERVER]: Handling {0} packet acks for {1} in {2}",
1180// ackPacket.Packets.Length, client.Name, m_scene.Name);
1181
846 for (int i = 0; i < ackPacket.Packets.Length; i++) 1182 for (int i = 0; i < ackPacket.Packets.Length; i++)
847 udpClient.NeedAcks.Acknowledge(ackPacket.Packets[i].ID, now, packet.Header.Resent); 1183 udpClient.NeedAcks.Acknowledge(ackPacket.Packets[i].ID, now, packet.Header.Resent);
848 1184
@@ -856,6 +1192,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
856 1192
857 if (packet.Header.Reliable) 1193 if (packet.Header.Reliable)
858 { 1194 {
1195// m_log.DebugFormat(
1196// "[LLUDPSERVER]: Adding ack request for {0} {1} from {2} in {3}",
1197// packet.Type, packet.Header.Sequence, client.Name, m_scene.Name);
1198
859 udpClient.PendingAcks.Enqueue(packet.Header.Sequence); 1199 udpClient.PendingAcks.Enqueue(packet.Header.Sequence);
860 1200
861 // This is a somewhat odd sequence of steps to pull the client.BytesSinceLastACK value out, 1201 // This is a somewhat odd sequence of steps to pull the client.BytesSinceLastACK value out,
@@ -902,6 +1242,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
902 1242
903 if (packet.Type == PacketType.StartPingCheck) 1243 if (packet.Type == PacketType.StartPingCheck)
904 { 1244 {
1245// m_log.DebugFormat("[LLUDPSERVER]: Handling ping from {0} in {1}", client.Name, m_scene.Name);
1246
905 // We don't need to do anything else with ping checks 1247 // We don't need to do anything else with ping checks
906 StartPingCheckPacket startPing = (StartPingCheckPacket)packet; 1248 StartPingCheckPacket startPing = (StartPingCheckPacket)packet;
907 CompletePing(udpClient, startPing.PingID.PingID); 1249 CompletePing(udpClient, startPing.PingID.PingID);
@@ -921,13 +1263,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
921 1263
922 #endregion Ping Check Handling 1264 #endregion Ping Check Handling
923 1265
1266 IncomingPacket incomingPacket;
1267
924 // Inbox insertion 1268 // Inbox insertion
925 if (packet.Type == PacketType.AgentUpdate || 1269 if (UsePools)
926 packet.Type == PacketType.ChatFromViewer) 1270 {
927 packetInbox.EnqueueHigh(new IncomingPacket((LLClientView)client, packet)); 1271 incomingPacket = m_incomingPacketPool.GetObject();
1272 incomingPacket.Client = (LLClientView)client;
1273 incomingPacket.Packet = packet;
1274 }
1275 else
1276 {
1277 incomingPacket = new IncomingPacket((LLClientView)client, packet);
1278 }
1279
1280 if (incomingPacket.Packet.Type == PacketType.AgentUpdate ||
1281 incomingPacket.Packet.Type == PacketType.ChatFromViewer)
1282 packetInbox.EnqueueHigh(incomingPacket);
928 else 1283 else
929 packetInbox.EnqueueLow(new IncomingPacket((LLClientView)client, packet)); 1284 packetInbox.EnqueueLow(incomingPacket);
930// packetInbox.Enqueue(new IncomingPacket((LLClientView)client, packet));
931 } 1285 }
932 1286
933 #region BinaryStats 1287 #region BinaryStats
@@ -1013,21 +1367,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1013 1367
1014 private void HandleUseCircuitCode(object o) 1368 private void HandleUseCircuitCode(object o)
1015 { 1369 {
1016 IPEndPoint remoteEndPoint = null; 1370 IPEndPoint endPoint = null;
1017 IClientAPI client = null; 1371 IClientAPI client = null;
1018 1372
1019 try 1373 try
1020 { 1374 {
1021 // DateTime startTime = DateTime.Now; 1375 // DateTime startTime = DateTime.Now;
1022 object[] array = (object[])o; 1376 object[] array = (object[])o;
1023 UDPPacketBuffer buffer = (UDPPacketBuffer)array[0]; 1377 endPoint = (IPEndPoint)array[0];
1024 UseCircuitCodePacket uccp = (UseCircuitCodePacket)array[1]; 1378 UseCircuitCodePacket uccp = (UseCircuitCodePacket)array[1];
1025 1379
1026 m_log.DebugFormat( 1380 m_log.DebugFormat(
1027 "[LLUDPSERVER]: Handling UseCircuitCode request for circuit {0} to {1} from IP {2}", 1381 "[LLUDPSERVER]: Handling UseCircuitCode request for circuit {0} to {1} from IP {2}",
1028 uccp.CircuitCode.Code, m_scene.RegionInfo.RegionName, buffer.RemoteEndPoint); 1382 uccp.CircuitCode.Code, m_scene.RegionInfo.RegionName, endPoint);
1029
1030 remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint;
1031 1383
1032 AuthenticateResponse sessionInfo; 1384 AuthenticateResponse sessionInfo;
1033 if (IsClientAuthorized(uccp, out sessionInfo)) 1385 if (IsClientAuthorized(uccp, out sessionInfo))
@@ -1038,13 +1390,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1038 uccp.CircuitCode.Code, 1390 uccp.CircuitCode.Code,
1039 uccp.CircuitCode.ID, 1391 uccp.CircuitCode.ID,
1040 uccp.CircuitCode.SessionID, 1392 uccp.CircuitCode.SessionID,
1041 remoteEndPoint, 1393 endPoint,
1042 sessionInfo); 1394 sessionInfo);
1043 1395
1044 // Send ack straight away to let the viewer know that the connection is active. 1396 // Send ack straight away to let the viewer know that the connection is active.
1045 // The client will be null if it already exists (e.g. if on a region crossing the client sends a use 1397 // The client will be null if it already exists (e.g. if on a region crossing the client sends a use
1046 // circuit code to the existing child agent. This is not particularly obvious. 1398 // circuit code to the existing child agent. This is not particularly obvious.
1047 SendAckImmediate(remoteEndPoint, uccp.Header.Sequence); 1399 SendAckImmediate(endPoint, uccp.Header.Sequence);
1048 1400
1049 // We only want to send initial data to new clients, not ones which are being converted from child to root. 1401 // We only want to send initial data to new clients, not ones which are being converted from child to root.
1050 if (client != null) 1402 if (client != null)
@@ -1058,12 +1410,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1058 1410
1059 lock (m_pendingCache) 1411 lock (m_pendingCache)
1060 { 1412 {
1061 if (!m_pendingCache.TryGetValue(remoteEndPoint, out queue)) 1413 if (!m_pendingCache.TryGetValue(endPoint, out queue))
1062 { 1414 {
1063 m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present"); 1415 m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present");
1064 return; 1416 return;
1065 } 1417 }
1066 m_pendingCache.Remove(remoteEndPoint); 1418 m_pendingCache.Remove(endPoint);
1067 } 1419 }
1068 1420
1069 m_log.DebugFormat("[LLUDPSERVER]: Client created, processing pending queue, {0} entries", queue.Count); 1421 m_log.DebugFormat("[LLUDPSERVER]: Client created, processing pending queue, {0} entries", queue.Count);
@@ -1081,9 +1433,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1081 // Don't create clients for unauthorized requesters. 1433 // Don't create clients for unauthorized requesters.
1082 m_log.WarnFormat( 1434 m_log.WarnFormat(
1083 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", 1435 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}",
1084 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, remoteEndPoint); 1436 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint);
1085 lock (m_pendingCache) 1437 lock (m_pendingCache)
1086 m_pendingCache.Remove(remoteEndPoint); 1438 m_pendingCache.Remove(endPoint);
1087 } 1439 }
1088 1440
1089 // m_log.DebugFormat( 1441 // m_log.DebugFormat(
@@ -1095,7 +1447,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1095 { 1447 {
1096 m_log.ErrorFormat( 1448 m_log.ErrorFormat(
1097 "[LLUDPSERVER]: UseCircuitCode handling from endpoint {0}, client {1} {2} failed. Exception {3}{4}", 1449 "[LLUDPSERVER]: UseCircuitCode handling from endpoint {0}, client {1} {2} failed. Exception {3}{4}",
1098 remoteEndPoint != null ? remoteEndPoint.ToString() : "n/a", 1450 endPoint != null ? endPoint.ToString() : "n/a",
1099 client != null ? client.Name : "unknown", 1451 client != null ? client.Name : "unknown",
1100 client != null ? client.AgentId.ToString() : "unknown", 1452 client != null ? client.AgentId.ToString() : "unknown",
1101 e.Message, 1453 e.Message,
@@ -1160,20 +1512,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1160 { 1512 {
1161 IClientAPI client = null; 1513 IClientAPI client = null;
1162 1514
1163 // In priciple there shouldn't be more than one thread here, ever. 1515 // We currently synchronize this code across the whole scene to avoid issues such as
1164 // But in case that happens, we need to synchronize this piece of code 1516 // http://opensimulator.org/mantis/view.php?id=5365 However, once locking per agent circuit can be done
1165 // because it's too important 1517 // consistently, this lock could probably be removed.
1166 lock (this) 1518 lock (this)
1167 { 1519 {
1168 if (!m_scene.TryGetClient(agentID, out client)) 1520 if (!m_scene.TryGetClient(agentID, out client))
1169 { 1521 {
1170 LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO); 1522 LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO);
1171 1523
1172 client = new LLClientView(m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode); 1524 client = new LLClientView(m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
1173 client.OnLogout += LogoutHandler; 1525 client.OnLogout += LogoutHandler;
1174 1526
1175 ((LLClientView)client).DisableFacelights = m_disableFacelights; 1527 ((LLClientView)client).DisableFacelights = m_disableFacelights;
1176 1528
1177 client.Start(); 1529 client.Start();
1178 } 1530 }
1179 } 1531 }
@@ -1212,7 +1564,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1212 // on to en-US to avoid number parsing issues 1564 // on to en-US to avoid number parsing issues
1213 Culture.SetCurrentCulture(); 1565 Culture.SetCurrentCulture();
1214 1566
1215 while (base.IsRunning) 1567 while (IsRunningInbound)
1216 { 1568 {
1217 m_scene.ThreadAlive(1); 1569 m_scene.ThreadAlive(1);
1218 try 1570 try
@@ -1228,7 +1580,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1228 } 1580 }
1229 1581
1230 if (packetInbox.Dequeue(100, ref incomingPacket)) 1582 if (packetInbox.Dequeue(100, ref incomingPacket))
1583 {
1231 ProcessInPacket(incomingPacket);//, incomingPacket); Util.FireAndForget(ProcessInPacket, incomingPacket); 1584 ProcessInPacket(incomingPacket);//, incomingPacket); Util.FireAndForget(ProcessInPacket, incomingPacket);
1585
1586 if (UsePools)
1587 m_incomingPacketPool.ReturnObject(incomingPacket);
1588 }
1232 } 1589 }
1233 catch (Exception ex) 1590 catch (Exception ex)
1234 { 1591 {
@@ -1255,7 +1612,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1255 // Action generic every round 1612 // Action generic every round
1256 Action<IClientAPI> clientPacketHandler = ClientOutgoingPacketHandler; 1613 Action<IClientAPI> clientPacketHandler = ClientOutgoingPacketHandler;
1257 1614
1258 while (base.IsRunning) 1615 while (base.IsRunningOutbound)
1259 { 1616 {
1260 m_scene.ThreadAlive(2); 1617 m_scene.ThreadAlive(2);
1261 try 1618 try
@@ -1383,6 +1740,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1383 private int npacksSent = 0; 1740 private int npacksSent = 0;
1384 private int npackNotSent = 0; 1741 private int npackNotSent = 0;
1385 1742
1743 /// <summary>
1744 /// Number of inbound packets processed since startup.
1745 /// </summary>
1746 public long IncomingPacketsProcessed { get; private set; }
1747
1386 private void MonitoredClientOutgoingPacketHandler(IClientAPI client) 1748 private void MonitoredClientOutgoingPacketHandler(IClientAPI client)
1387 { 1749 {
1388 nticks++; 1750 nticks++;
@@ -1442,7 +1804,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1442 npacksSent++; 1804 npacksSent++;
1443 } 1805 }
1444 else 1806 else
1807 {
1445 npackNotSent++; 1808 npackNotSent++;
1809 }
1446 1810
1447 watch2.Stop(); 1811 watch2.Stop();
1448 avgDequeueTicks = (nticks - 1) / (float)nticks * avgDequeueTicks + (watch2.ElapsedTicks / (float)nticks); 1812 avgDequeueTicks = (nticks - 1) / (float)nticks * avgDequeueTicks + (watch2.ElapsedTicks / (float)nticks);
@@ -1450,7 +1814,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1450 1814
1451 } 1815 }
1452 else 1816 else
1817 {
1453 m_log.WarnFormat("[LLUDPSERVER]: Client is not connected"); 1818 m_log.WarnFormat("[LLUDPSERVER]: Client is not connected");
1819 }
1454 } 1820 }
1455 } 1821 }
1456 catch (Exception ex) 1822 catch (Exception ex)
@@ -1514,6 +1880,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1514// "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", 1880// "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}",
1515// packet.Type, client.Name, m_scene.RegionInfo.RegionName); 1881// packet.Type, client.Name, m_scene.RegionInfo.RegionName);
1516// } 1882// }
1883
1884 IncomingPacketsProcessed++;
1517 } 1885 }
1518 1886
1519 protected void LogoutHandler(IClientAPI client) 1887 protected void LogoutHandler(IClientAPI client)
@@ -1523,7 +1891,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1523 if (!client.IsLoggingOut) 1891 if (!client.IsLoggingOut)
1524 { 1892 {
1525 client.IsLoggingOut = true; 1893 client.IsLoggingOut = true;
1526 client.Close(false); 1894 client.Close(false, false);
1527 } 1895 }
1528 } 1896 }
1529 } 1897 }
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
index cfe7c9d..2aeb4cc 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
@@ -30,6 +30,8 @@ using System.Net;
30using System.Net.Sockets; 30using System.Net.Sockets;
31using System.Threading; 31using System.Threading;
32using log4net; 32using log4net;
33using OpenSim.Framework;
34using OpenSim.Framework.Monitoring;
33 35
34namespace OpenMetaverse 36namespace OpenMetaverse
35{ 37{
@@ -58,17 +60,29 @@ namespace OpenMetaverse
58 /// <summary>Flag to process packets asynchronously or synchronously</summary> 60 /// <summary>Flag to process packets asynchronously or synchronously</summary>
59 private bool m_asyncPacketHandling; 61 private bool m_asyncPacketHandling;
60 62
61 /// <summary>The all important shutdown flag</summary> 63 /// <summary>
62 private volatile bool m_shutdownFlag = true; 64 /// Are we to use object pool(s) to reduce memory churn when receiving data?
65 /// </summary>
66 public bool UsePools { get; protected set; }
67
68 /// <summary>
69 /// Pool to use for handling data. May be null if UsePools = false;
70 /// </summary>
71 protected OpenSim.Framework.Pool<UDPPacketBuffer> Pool { get; private set; }
72
73 /// <summary>Returns true if the server is currently listening for inbound packets, otherwise false</summary>
74 public bool IsRunningInbound { get; private set; }
63 75
64 /// <summary>Returns true if the server is currently listening, otherwise false</summary> 76 /// <summary>Returns true if the server is currently sending outbound packets, otherwise false</summary>
65 public bool IsRunning { get { return !m_shutdownFlag; } } 77 /// <remarks>If IsRunningOut = false, then any request to send a packet is simply dropped.</remarks>
78 public bool IsRunningOutbound { get; private set; }
66 79
67 /// <summary> 80 /// <summary>
68 /// Default constructor 81 /// Default constructor
69 /// </summary> 82 /// </summary>
70 /// <param name="bindAddress">Local IP address to bind the server to</param> 83 /// <param name="bindAddress">Local IP address to bind the server to</param>
71 /// <param name="port">Port to listening for incoming UDP packets on</param> 84 /// <param name="port">Port to listening for incoming UDP packets on</param>
85 /// /// <param name="usePool">Are we to use an object pool to get objects for handing inbound data?</param>
72 public OpenSimUDPBase(IPAddress bindAddress, int port) 86 public OpenSimUDPBase(IPAddress bindAddress, int port)
73 { 87 {
74 m_localBindAddress = bindAddress; 88 m_localBindAddress = bindAddress;
@@ -76,7 +90,7 @@ namespace OpenMetaverse
76 } 90 }
77 91
78 /// <summary> 92 /// <summary>
79 /// Start the UDP server 93 /// Start inbound UDP packet handling.
80 /// </summary> 94 /// </summary>
81 /// <param name="recvBufferSize">The size of the receive buffer for 95 /// <param name="recvBufferSize">The size of the receive buffer for
82 /// the UDP socket. This value is passed up to the operating system 96 /// the UDP socket. This value is passed up to the operating system
@@ -91,11 +105,11 @@ namespace OpenMetaverse
91 /// manner (not throwing an exception when the remote side resets the 105 /// manner (not throwing an exception when the remote side resets the
92 /// connection). This call is ignored on Mono where the flag is not 106 /// connection). This call is ignored on Mono where the flag is not
93 /// necessary</remarks> 107 /// necessary</remarks>
94 public void Start(int recvBufferSize, bool asyncPacketHandling) 108 public void StartInbound(int recvBufferSize, bool asyncPacketHandling)
95 { 109 {
96 m_asyncPacketHandling = asyncPacketHandling; 110 m_asyncPacketHandling = asyncPacketHandling;
97 111
98 if (m_shutdownFlag) 112 if (!IsRunningInbound)
99 { 113 {
100 const int SIO_UDP_CONNRESET = -1744830452; 114 const int SIO_UDP_CONNRESET = -1744830452;
101 115
@@ -123,8 +137,7 @@ namespace OpenMetaverse
123 137
124 m_udpSocket.Bind(ipep); 138 m_udpSocket.Bind(ipep);
125 139
126 // we're not shutting down, we're starting up 140 IsRunningInbound = true;
127 m_shutdownFlag = false;
128 141
129 // kick off an async receive. The Start() method will return, the 142 // kick off an async receive. The Start() method will return, the
130 // actual receives will occur asynchronously and will be caught in 143 // actual receives will occur asynchronously and will be caught in
@@ -134,28 +147,69 @@ namespace OpenMetaverse
134 } 147 }
135 148
136 /// <summary> 149 /// <summary>
137 /// Stops the UDP server 150 /// Start outbound UDP packet handling.
138 /// </summary> 151 /// </summary>
139 public void Stop() 152 public void StartOutbound()
140 { 153 {
141 if (!m_shutdownFlag) 154 IsRunningOutbound = true;
155 }
156
157 public void StopInbound()
158 {
159 if (IsRunningInbound)
142 { 160 {
143 // wait indefinitely for a writer lock. Once this is called, the .NET runtime 161 // wait indefinitely for a writer lock. Once this is called, the .NET runtime
144 // will deny any more reader locks, in effect blocking all other send/receive 162 // will deny any more reader locks, in effect blocking all other send/receive
145 // threads. Once we have the lock, we set shutdownFlag to inform the other 163 // threads. Once we have the lock, we set IsRunningInbound = false to inform the other
146 // threads that the socket is closed. 164 // threads that the socket is closed.
147 m_shutdownFlag = true; 165 IsRunningInbound = false;
148 m_udpSocket.Close(); 166 m_udpSocket.Close();
149 } 167 }
150 } 168 }
151 169
170 public void StopOutbound()
171 {
172 IsRunningOutbound = false;
173 }
174
175 protected virtual bool EnablePools()
176 {
177 if (!UsePools)
178 {
179 Pool = new Pool<UDPPacketBuffer>(() => new UDPPacketBuffer(), 500);
180
181 UsePools = true;
182
183 return true;
184 }
185
186 return false;
187 }
188
189 protected virtual bool DisablePools()
190 {
191 if (UsePools)
192 {
193 UsePools = false;
194
195 // We won't null out the pool to avoid a race condition with code that may be in the middle of using it.
196
197 return true;
198 }
199
200 return false;
201 }
202
152 private void AsyncBeginReceive() 203 private void AsyncBeginReceive()
153 { 204 {
154 // allocate a packet buffer 205 UDPPacketBuffer buf;
155 //WrappedObject<UDPPacketBuffer> wrappedBuffer = Pool.CheckOut(); 206
156 UDPPacketBuffer buf = new UDPPacketBuffer(); 207 if (UsePools)
208 buf = Pool.GetObject();
209 else
210 buf = new UDPPacketBuffer();
157 211
158 if (!m_shutdownFlag) 212 if (IsRunningInbound)
159 { 213 {
160 try 214 try
161 { 215 {
@@ -208,7 +262,7 @@ namespace OpenMetaverse
208 { 262 {
209 // Asynchronous receive operations will complete here through the call 263 // Asynchronous receive operations will complete here through the call
210 // to AsyncBeginReceive 264 // to AsyncBeginReceive
211 if (!m_shutdownFlag) 265 if (IsRunningInbound)
212 { 266 {
213 // Asynchronous mode will start another receive before the 267 // Asynchronous mode will start another receive before the
214 // callback for this packet is even fired. Very parallel :-) 268 // callback for this packet is even fired. Very parallel :-)
@@ -217,8 +271,6 @@ namespace OpenMetaverse
217 271
218 // get the buffer that was created in AsyncBeginReceive 272 // get the buffer that was created in AsyncBeginReceive
219 // this is the received data 273 // this is the received data
220 //WrappedObject<UDPPacketBuffer> wrappedBuffer = (WrappedObject<UDPPacketBuffer>)iar.AsyncState;
221 //UDPPacketBuffer buffer = wrappedBuffer.Instance;
222 UDPPacketBuffer buffer = (UDPPacketBuffer)iar.AsyncState; 274 UDPPacketBuffer buffer = (UDPPacketBuffer)iar.AsyncState;
223 275
224 try 276 try
@@ -235,7 +287,8 @@ namespace OpenMetaverse
235 catch (ObjectDisposedException) { } 287 catch (ObjectDisposedException) { }
236 finally 288 finally
237 { 289 {
238 //wrappedBuffer.Dispose(); 290 if (UsePools)
291 Pool.ReturnObject(buffer);
239 292
240 // Synchronous mode waits until the packet callback completes 293 // Synchronous mode waits until the packet callback completes
241 // before starting the receive to fetch another packet 294 // before starting the receive to fetch another packet
@@ -248,7 +301,7 @@ namespace OpenMetaverse
248 301
249 public void AsyncBeginSend(UDPPacketBuffer buf) 302 public void AsyncBeginSend(UDPPacketBuffer buf)
250 { 303 {
251 if (!m_shutdownFlag) 304 if (IsRunningOutbound)
252 { 305 {
253 try 306 try
254 { 307 {
@@ -277,4 +330,4 @@ namespace OpenMetaverse
277 catch (ObjectDisposedException) { } 330 catch (ObjectDisposedException) { }
278 } 331 }
279 } 332 }
280} 333} \ No newline at end of file
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
new file mode 100644
index 0000000..1fdc410
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
@@ -0,0 +1,306 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using OpenMetaverse;
32using OpenMetaverse.Packets;
33using log4net;
34using OpenSim.Framework.Monitoring;
35
36namespace OpenSim.Region.ClientStack.LindenUDP
37{
38 public sealed class PacketPool
39 {
40 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
41
42 private static readonly PacketPool instance = new PacketPool();
43
44 /// <summary>
45 /// Pool of packets available for reuse.
46 /// </summary>
47 private readonly Dictionary<PacketType, Stack<Packet>> pool = new Dictionary<PacketType, Stack<Packet>>();
48
49 private static Dictionary<Type, Stack<Object>> DataBlocks = new Dictionary<Type, Stack<Object>>();
50
51 public static PacketPool Instance
52 {
53 get { return instance; }
54 }
55
56 public bool RecyclePackets { get; set; }
57
58 public bool RecycleDataBlocks { get; set; }
59
60 /// <summary>
61 /// The number of packets pooled
62 /// </summary>
63 public int PacketsPooled
64 {
65 get
66 {
67 lock (pool)
68 return pool.Count;
69 }
70 }
71
72 /// <summary>
73 /// The number of blocks pooled.
74 /// </summary>
75 public int BlocksPooled
76 {
77 get
78 {
79 lock (DataBlocks)
80 return DataBlocks.Count;
81 }
82 }
83
84 /// <summary>
85 /// Number of packets requested.
86 /// </summary>
87 public long PacketsRequested { get; private set; }
88
89 /// <summary>
90 /// Number of packets reused.
91 /// </summary>
92 public long PacketsReused { get; private set; }
93
94 /// <summary>
95 /// Number of packet blocks requested.
96 /// </summary>
97 public long BlocksRequested { get; private set; }
98
99 /// <summary>
100 /// Number of packet blocks reused.
101 /// </summary>
102 public long BlocksReused { get; private set; }
103
104 private PacketPool()
105 {
106 // defaults
107 RecyclePackets = true;
108 RecycleDataBlocks = true;
109 }
110
111 /// <summary>
112 /// Gets a packet of the given type.
113 /// </summary>
114 /// <param name='type'></param>
115 /// <returns>Guaranteed to always return a packet, whether from the pool or newly constructed.</returns>
116 public Packet GetPacket(PacketType type)
117 {
118 PacketsRequested++;
119
120 Packet packet;
121
122 if (!RecyclePackets)
123 return Packet.BuildPacket(type);
124
125 lock (pool)
126 {
127 if (!pool.ContainsKey(type) || pool[type] == null || (pool[type]).Count == 0)
128 {
129// m_log.DebugFormat("[PACKETPOOL]: Building {0} packet", type);
130
131 // Creating a new packet if we cannot reuse an old package
132 packet = Packet.BuildPacket(type);
133 }
134 else
135 {
136// m_log.DebugFormat("[PACKETPOOL]: Pulling {0} packet", type);
137
138 // Recycle old packages
139 PacketsReused++;
140
141 packet = pool[type].Pop();
142 }
143 }
144
145 return packet;
146 }
147
148 // private byte[] decoded_header = new byte[10];
149 private static PacketType GetType(byte[] bytes)
150 {
151 byte[] decoded_header = new byte[10 + 8];
152 ushort id;
153 PacketFrequency freq;
154
155 if ((bytes[0] & Helpers.MSG_ZEROCODED) != 0)
156 {
157 Helpers.ZeroDecode(bytes, 16, decoded_header);
158 }
159 else
160 {
161 Buffer.BlockCopy(bytes, 0, decoded_header, 0, 10);
162 }
163
164 if (decoded_header[6] == 0xFF)
165 {
166 if (decoded_header[7] == 0xFF)
167 {
168 id = (ushort) ((decoded_header[8] << 8) + decoded_header[9]);
169 freq = PacketFrequency.Low;
170 }
171 else
172 {
173 id = decoded_header[7];
174 freq = PacketFrequency.Medium;
175 }
176 }
177 else
178 {
179 id = decoded_header[6];
180 freq = PacketFrequency.High;
181 }
182
183 return Packet.GetType(id, freq);
184 }
185
186 public Packet GetPacket(byte[] bytes, ref int packetEnd, byte[] zeroBuffer)
187 {
188 PacketType type = GetType(bytes);
189
190// Array.Clear(zeroBuffer, 0, zeroBuffer.Length);
191
192 int i = 0;
193 Packet packet = GetPacket(type);
194 if (packet == null)
195 m_log.WarnFormat("[PACKETPOOL]: Failed to get packet of type {0}", type);
196 else
197 packet.FromBytes(bytes, ref i, ref packetEnd, zeroBuffer);
198
199 return packet;
200 }
201
202 /// <summary>
203 /// Return a packet to the packet pool
204 /// </summary>
205 /// <param name="packet"></param>
206 public void ReturnPacket(Packet packet)
207 {
208 if (RecycleDataBlocks)
209 {
210 switch (packet.Type)
211 {
212 case PacketType.ObjectUpdate:
213 ObjectUpdatePacket oup = (ObjectUpdatePacket)packet;
214
215 foreach (ObjectUpdatePacket.ObjectDataBlock oupod in oup.ObjectData)
216 ReturnDataBlock<ObjectUpdatePacket.ObjectDataBlock>(oupod);
217
218 oup.ObjectData = null;
219 break;
220
221 case PacketType.ImprovedTerseObjectUpdate:
222 ImprovedTerseObjectUpdatePacket itoup = (ImprovedTerseObjectUpdatePacket)packet;
223
224 foreach (ImprovedTerseObjectUpdatePacket.ObjectDataBlock itoupod in itoup.ObjectData)
225 ReturnDataBlock<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(itoupod);
226
227 itoup.ObjectData = null;
228 break;
229 }
230 }
231
232 if (RecyclePackets)
233 {
234 switch (packet.Type)
235 {
236 // List pooling packets here
237 case PacketType.AgentUpdate:
238 case PacketType.PacketAck:
239 case PacketType.ObjectUpdate:
240 case PacketType.ImprovedTerseObjectUpdate:
241 lock (pool)
242 {
243 PacketType type = packet.Type;
244
245 if (!pool.ContainsKey(type))
246 {
247 pool[type] = new Stack<Packet>();
248 }
249
250 if ((pool[type]).Count < 50)
251 {
252// m_log.DebugFormat("[PACKETPOOL]: Pushing {0} packet", type);
253
254 pool[type].Push(packet);
255 }
256 }
257 break;
258
259 // Other packets wont pool
260 default:
261 return;
262 }
263 }
264 }
265
266 public T GetDataBlock<T>() where T: new()
267 {
268 lock (DataBlocks)
269 {
270 BlocksRequested++;
271
272 Stack<Object> s;
273
274 if (DataBlocks.TryGetValue(typeof(T), out s))
275 {
276 if (s.Count > 0)
277 {
278 BlocksReused++;
279 return (T)s.Pop();
280 }
281 }
282 else
283 {
284 DataBlocks[typeof(T)] = new Stack<Object>();
285 }
286
287 return new T();
288 }
289 }
290
291 public void ReturnDataBlock<T>(T block) where T: new()
292 {
293 if (block == null)
294 return;
295
296 lock (DataBlocks)
297 {
298 if (!DataBlocks.ContainsKey(typeof(T)))
299 DataBlocks[typeof(T)] = new Stack<Object>();
300
301 if (DataBlocks[typeof(T)].Count < 50)
302 DataBlocks[typeof(T)].Push(block);
303 }
304 }
305 }
306} \ No newline at end of file
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs b/OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..af2f6f8
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs
@@ -0,0 +1,33 @@
1using System.Reflection;
2using System.Runtime.CompilerServices;
3using System.Runtime.InteropServices;
4
5// General Information about an assembly is controlled through the following
6// set of attributes. Change these attribute values to modify the information
7// associated with an assembly.
8[assembly: AssemblyTitle("OpenSim.Region.ClientStack.LindenUDP")]
9[assembly: AssemblyDescription("")]
10[assembly: AssemblyConfiguration("")]
11[assembly: AssemblyCompany("http://opensimulator.org")]
12[assembly: AssemblyProduct("OpenSim")]
13[assembly: AssemblyCopyright("OpenSimulator developers")]
14[assembly: AssemblyTrademark("")]
15[assembly: AssemblyCulture("")]
16
17// Setting ComVisible to false makes the types in this assembly not visible
18// to COM components. If you need to access a type in this assembly from
19// COM, set the ComVisible attribute to true on that type.
20[assembly: ComVisible(false)]
21
22// The following GUID is for the ID of the typelib if this project is exposed to COM
23[assembly: Guid("9d3dbc6b-9d85-483b-af48-c1dfc261b7ac")]
24
25// Version information for an assembly consists of the following four values:
26//
27// Major Version
28// Minor Version
29// Build Number
30// Revision
31//
32[assembly: AssemblyVersion("0.7.5.*")]
33[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs
index 109a8e1..556df30 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs
@@ -43,7 +43,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
43 /// This will contain basic tests for the LindenUDP client stack 43 /// This will contain basic tests for the LindenUDP client stack
44 /// </summary> 44 /// </summary>
45 [TestFixture] 45 [TestFixture]
46 public class BasicCircuitTests 46 public class BasicCircuitTests : OpenSimTestCase
47 { 47 {
48 private Scene m_scene; 48 private Scene m_scene;
49 private TestLLUDPServer m_udpServer; 49 private TestLLUDPServer m_udpServer;
@@ -65,8 +65,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
65 } 65 }
66 66
67 [SetUp] 67 [SetUp]
68 public void SetUp() 68 public override void SetUp()
69 { 69 {
70 base.SetUp();
70 m_scene = new SceneHelpers().SetupScene(); 71 m_scene = new SceneHelpers().SetupScene();
71 } 72 }
72 73
@@ -143,7 +144,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
143 public void TestAddClient() 144 public void TestAddClient()
144 { 145 {
145 TestHelpers.InMethod(); 146 TestHelpers.InMethod();
146// XmlConfigurator.Configure(); 147// TestHelpers.EnableLogging();
147 148
148 AddUdpServer(); 149 AddUdpServer();
149 150