diff --git a/OpenSim/Data/MySQL/MySQLXAssetData.cs b/OpenSim/Data/MySQL/MySQLXAssetData.cs index 692ade7179..7b634e2b09 100644 --- a/OpenSim/Data/MySQL/MySQLXAssetData.cs +++ b/OpenSim/Data/MySQL/MySQLXAssetData.cs @@ -162,7 +162,7 @@ namespace OpenSim.Data.MySQL using (GZipStream decompressionStream = new GZipStream(new MemoryStream(asset.Data), CompressionMode.Decompress)) { MemoryStream outputStream = new MemoryStream(); - WebUtil.CopyTo(decompressionStream, outputStream, int.MaxValue); + WebUtil.CopyStream(decompressionStream, outputStream, int.MaxValue); // int compressedLength = asset.Data.Length; asset.Data = outputStream.ToArray(); diff --git a/OpenSim/Framework/MultipartForm.cs b/OpenSim/Framework/MultipartForm.cs index 90c4007ddc..7a13e8b21c 100644 --- a/OpenSim/Framework/MultipartForm.cs +++ b/OpenSim/Framework/MultipartForm.cs @@ -119,7 +119,7 @@ namespace OpenSim.Framework // Copy the temporary stream to the network stream formDataStream.Seek(0, SeekOrigin.Begin); using (Stream requestStream = request.GetRequestStream()) - formDataStream.CopyTo(requestStream, (int)formDataStream.Length); + formDataStream.CopyStream(requestStream, (int)formDataStream.Length); } #endregion Stream Writing diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs index 71a56e5784..aac575cb5c 100644 --- a/OpenSim/Framework/WebUtil.cs +++ b/OpenSim/Framework/WebUtil.cs @@ -511,8 +511,13 @@ namespace OpenSim.Framework /// /// Copying begins at the streams' current positions. The positions are /// NOT reset after copying is complete. + /// NOTE!! .NET 4.0 adds the method 'Stream.CopyTo(stream, bufferSize)'. + /// This function could be replaced with that method once we move + /// totally to .NET 4.0. For versions before, this routine exists. + /// This routine used to be named 'CopyTo' but the int parameter has + /// a different meaning so this method was renamed to avoid any confusion. /// - public static int CopyTo(this Stream copyFrom, Stream copyTo, int maximumBytesToCopy) + public static int CopyStream(this Stream copyFrom, Stream copyTo, int maximumBytesToCopy) { byte[] buffer = new byte[4096]; int readBytes; diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 60a8f86651..feab40e4f0 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -305,6 +305,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } + if (IsInTransit(sp.UUID)) // Avie is already on the way. Caller shouldn't do this. + return; + m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Request Teleport to {0} ({1}) {2}/{3}", reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position); @@ -1825,6 +1828,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } } + protected bool IsInTransit(UUID id) + { + lock (m_agentsInTransit) + { + if (m_agentsInTransit.Contains(id)) + return true; + } + return false; + } + protected bool ResetFromTransit(UUID id) { lock (m_agentsInTransit) diff --git a/OpenSim/Region/DataSnapshot/DataRequestHandler.cs b/OpenSim/Region/DataSnapshot/DataRequestHandler.cs index 93648d6430..2f2b3e6743 100644 --- a/OpenSim/Region/DataSnapshot/DataRequestHandler.cs +++ b/OpenSim/Region/DataSnapshot/DataRequestHandler.cs @@ -46,8 +46,6 @@ namespace OpenSim.Region.DataSnapshot private DataSnapshotManager m_externalData = null; private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private readonly string m_discoveryPath = "DS0001/"; - public DataRequestHandler(Scene scene, DataSnapshotManager externalData) { m_scene = scene; @@ -58,37 +56,9 @@ namespace OpenSim.Region.DataSnapshot { m_log.Info("[DATASNAPSHOT]: Set up snapshot service"); } + // Register validation callback handler + MainServer.Instance.AddHTTPHandler("validate", OnValidate); - //Register CAPS handler event - m_scene.EventManager.OnRegisterCaps += OnRegisterCaps; - - //harbl - } - - public void OnRegisterCaps(UUID agentID, Caps caps) - { -// m_log.InfoFormat("[DATASNAPSHOT]: Registering service discovery capability for {0}", agentID); - string capsBase = "/CAPS/" + caps.CapsObjectPath; - caps.RegisterHandler("PublicSnapshotDataInfo", - new RestStreamHandler("POST", capsBase + m_discoveryPath, OnDiscoveryAttempt)); - } - - public string OnDiscoveryAttempt(string request, string path, string param, - IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) - { - //Very static for now, flexible enough to add new formats - LLSDDiscoveryResponse llsd_response = new LLSDDiscoveryResponse(); - llsd_response.snapshot_resources = new OSDArray(); - - LLSDDiscoveryDataURL llsd_dataurl = new LLSDDiscoveryDataURL(); - llsd_dataurl.snapshot_format = "os-datasnapshot-v1"; - llsd_dataurl.snapshot_url = "http://" + m_externalData.m_hostname + ":" + m_externalData.m_listener_port + "/?method=collector"; - - llsd_response.snapshot_resources.Array.Add(llsd_dataurl); - - string response = LLSDHelpers.SerialiseLLSDReply(llsd_response); - - return response; } public Hashtable OnGetSnapshot(Hashtable keysvals) @@ -107,5 +77,23 @@ namespace OpenSim.Region.DataSnapshot return reply; } + + public Hashtable OnValidate(Hashtable keysvals) + { + m_log.Info("[DATASNAPSHOT] Received validation request"); + Hashtable reply = new Hashtable(); + int statuscode = 200; + + string secret = (string)keysvals["secret"]; + if (secret == m_externalData.Secret.ToString()) + statuscode = 403; + + reply["str_response_string"] = string.Empty; + reply["int_response_code"] = statuscode; + reply["content_type"] = "text/plain"; + + return reply; + } + } } diff --git a/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs b/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs index 9fc002b7b9..5540656cc1 100644 --- a/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs +++ b/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs @@ -66,6 +66,7 @@ namespace OpenSim.Region.DataSnapshot private string m_dataServices = "noservices"; public string m_listener_port = ConfigSettings.DefaultRegionHttpPort.ToString(); public string m_hostname = "127.0.0.1"; + private UUID m_Secret = UUID.Random(); //Update timers private int m_period = 20; // in seconds @@ -85,6 +86,11 @@ namespace OpenSim.Region.DataSnapshot get { return m_exposure_level; } } + public UUID Secret + { + get { return m_Secret; } + } + #endregion #region IRegionModule @@ -103,10 +109,10 @@ namespace OpenSim.Region.DataSnapshot m_enabled = config.Configs["DataSnapshot"].GetBoolean("index_sims", m_enabled); IConfig conf = config.Configs["GridService"]; if (conf != null) - m_gridinfo.Add("gridserverURL", conf.GetString("GridServerURI", "http://127.0.0.1:8003")); + m_gridinfo.Add("gatekeeperURL", conf.GetString("Gatekeeper", String.Empty)); m_gridinfo.Add( - "Name", config.Configs["DataSnapshot"].GetString("gridname", "the lost continent of hippo")); + "name", config.Configs["DataSnapshot"].GetString("gridname", "the lost continent of hippo")); m_exposure_level = config.Configs["DataSnapshot"].GetString("data_exposure", m_exposure_level); m_period = config.Configs["DataSnapshot"].GetInt("default_snapshot_period", m_period); m_maxStales = config.Configs["DataSnapshot"].GetInt("max_changes_before_update", m_maxStales); @@ -315,6 +321,7 @@ namespace OpenSim.Region.DataSnapshot cli.AddQueryParameter("service", serviceName); cli.AddQueryParameter("host", m_hostname); cli.AddQueryParameter("port", m_listener_port); + cli.AddQueryParameter("secret", m_Secret.ToString()); cli.RequestMethod = "GET"; try { @@ -341,7 +348,7 @@ namespace OpenSim.Region.DataSnapshot } // This is not quite working, so... // string responseStr = Util.UTF8.GetString(response); - m_log.Info("[DATASNAPSHOT]: data service notified: " + url); + m_log.Info("[DATASNAPSHOT]: data service " + url + " notified. Secret: " + m_Secret); } } diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs index d3200d58ae..f00e41f3e1 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs @@ -89,7 +89,7 @@ namespace OpenSim.Region.ScriptEngine.Interfaces void Start(); /// - /// Stop the script. + /// Stop the script instance. /// /// /// true if the script was successfully stopped, false otherwise @@ -97,13 +97,17 @@ namespace OpenSim.Region.ScriptEngine.Interfaces void SetState(string state); + /// + /// Post an event to this script instance. + /// + /// void PostEvent(EventParams data); void Suspend(); void Resume(); /// - /// Process the next event queued for this script + /// Process the next event queued for this script instance. /// /// object EventProcessor(); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index ecc5fb5b4c..8dfc7d2695 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2102,6 +2102,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return HomeURI; } + public string osGetGridGatekeeperURI() + { + CheckThreatLevel(ThreatLevel.Moderate, "osGetGridGatekeeperURI"); + m_host.AddScriptLPS(1); + + string gatekeeperURI = String.Empty; + IConfigSource config = m_ScriptEngine.ConfigSource; + + if (config.Configs["GridService"] != null) + gatekeeperURI = config.Configs["GridService"].GetString("Gatekeeper", gatekeeperURI); + + return gatekeeperURI; + } + public string osGetGridCustom(string key) { CheckThreatLevel(ThreatLevel.Moderate, "osGetGridCustom"); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index fb52600fb6..e59d3a8020 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -161,6 +161,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces string osGetGridName(); string osGetGridLoginURI(); string osGetGridHomeURI(); + string osGetGridGatekeeperURI(); string osGetGridCustom(string key); LSL_String osFormatString(string str, LSL_List strings); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 4341246f07..e048da2ce9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -457,6 +457,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_OSSL_Functions.osGetGridHomeURI(); } + public string osGetGridGatekeeperURI() + { + return m_OSSL_Functions.osGetGridGatekeeperURI(); + } + public string osGetGridCustom(string key) { return m_OSSL_Functions.osGetGridCustom(key); diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index da2ef7b2b1..6d56437a11 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -59,7 +59,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private IScriptEngine m_Engine; - private IScriptWorkItem m_CurrentResult = null; + + /// + /// The current work item if an event for this script is running or waiting to run, + /// + /// + /// Null if there is no running or waiting to run event. Must be changed only under an m_EventQueue lock. + /// + private IScriptWorkItem m_CurrentWorkItem; + private Queue m_EventQueue = new Queue(32); private bool m_RunEvents = false; private UUID m_ItemID; @@ -158,7 +166,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance { // Need to place ourselves back in a work item if there are events to process if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) - m_CurrentResult = m_Engine.QueueEventHandler(this); + m_CurrentWorkItem = m_Engine.QueueEventHandler(this); } } } @@ -528,8 +536,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance if (m_EventQueue.Count > 0) { - if (m_CurrentResult == null) - m_CurrentResult = m_Engine.QueueEventHandler(this); + if (m_CurrentWorkItem == null) + m_CurrentWorkItem = m_Engine.QueueEventHandler(this); // else // m_log.Error("[Script] Tried to start a script that was already queued"); } @@ -541,49 +549,58 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance // m_log.DebugFormat( // "[SCRIPT INSTANCE]: Stopping script {0} {1} with timeout {2}", ScriptName, ItemID, timeout); - IScriptWorkItem result; + IScriptWorkItem workItem; lock (m_EventQueue) { if (!Running) return true; - if (m_CurrentResult == null) + // If we're not running or waiting to run an event then we can safely stop. + if (m_CurrentWorkItem == null) { m_RunEvents = false; return true; } - if (m_CurrentResult.Cancel()) + // If we are waiting to run an event then we can try to cancel it. + if (m_CurrentWorkItem.Cancel()) { - m_CurrentResult = null; + m_CurrentWorkItem = null; m_RunEvents = false; return true; } - result = m_CurrentResult; + workItem = m_CurrentWorkItem; m_RunEvents = false; } - if (result.Wait(new TimeSpan((long)timeout * 100000))) + // Wait for the current event to complete. + if (workItem.Wait(new TimeSpan((long)timeout * 100000))) { return true; } lock (m_EventQueue) { - result = m_CurrentResult; + workItem = m_CurrentWorkItem; } - if (result == null) + if (workItem == null) return true; + // If the event still hasn't stopped and we the stop isn't the result of script or object removal, then + // forcibly abort the work item (this aborts the underlying thread). if (!m_InSelfDelete) - result.Abort(); + { +// m_log.ErrorFormat("[SCRIPT INSTANCE]: Aborting script {0} {1}", ScriptName, ItemID); + + workItem.Abort(); + } lock (m_EventQueue) { - m_CurrentResult = null; + m_CurrentWorkItem = null; } return true; @@ -605,6 +622,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance throw new EventAbortException(); } + /// + /// Post an event to this script instance. + /// + /// + /// The request to run the event is sent + /// + /// public void PostEvent(EventParams data) { // m_log.DebugFormat("[Script] Posted event {2} in state {3} to {0}.{1}", @@ -671,9 +695,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance m_EventQueue.Enqueue(data); - if (m_CurrentResult == null) + if (m_CurrentWorkItem == null) { - m_CurrentResult = m_Engine.QueueEventHandler(this); + m_CurrentWorkItem = m_Engine.QueueEventHandler(this); } } } @@ -698,11 +722,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance { if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) { - m_CurrentResult = m_Engine.QueueEventHandler(this); + if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) + { + m_CurrentWorkItem = m_Engine.QueueEventHandler(this); + } + else + { + m_CurrentWorkItem = null; + } + return 0; } else { - m_CurrentResult = null; + m_CurrentWorkItem = null; } return 0; } @@ -825,15 +857,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance } } + + // If there are more events and we are currently running and not shutting down, then ask the + // script engine to run the next event. lock (m_EventQueue) { if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) { - m_CurrentResult = m_Engine.QueueEventHandler(this); + m_CurrentWorkItem = m_Engine.QueueEventHandler(this); } else { - m_CurrentResult = null; + m_CurrentWorkItem = null; } } @@ -941,8 +976,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance public void SaveState(string assembly) { - - // If we're currently in an event, just tell it to save upon return // if (m_InEvent) diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index db6a40755b..1d3ba6ceac 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -452,6 +452,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine sb.AppendFormat("Unique scripts : {0}\n", m_uniqueScripts.Count); sb.AppendFormat("Scripts waiting for load : {0}\n", m_CompileQueue.Count); + sb.AppendFormat("Max threads : {0}\n", m_ThreadPool.MaxThreads); + sb.AppendFormat("Min threads : {0}\n", m_ThreadPool.MinThreads); sb.AppendFormat("Allocated threads : {0}\n", m_ThreadPool.ActiveThreads); sb.AppendFormat("In use threads : {0}\n", m_ThreadPool.InUseThreads); sb.AppendFormat("Work items waiting : {0}\n", m_ThreadPool.WaitingCallbacks); diff --git a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs index ded335d5d3..8f6fa52cfd 100644 --- a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs +++ b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs @@ -295,23 +295,28 @@ namespace OpenSim.Server.Handlers.Simulation keysvals.Add("headers", headervals); keysvals.Add("querystringkeys", querystringkeys); - Stream inputStream; + httpResponse.StatusCode = 200; + httpResponse.ContentType = "text/html"; + httpResponse.KeepAlive = false; + Encoding encoding = Encoding.UTF8; + + Stream inputStream = null; if (httpRequest.ContentType == "application/x-gzip") inputStream = new GZipStream(request, CompressionMode.Decompress); - else + else if (httpRequest.ContentType == "application/json") inputStream = request; + else // no go + { + httpResponse.StatusCode = 406; + return encoding.GetBytes("false"); + } - Encoding encoding = Encoding.UTF8; StreamReader reader = new StreamReader(inputStream, encoding); string requestBody = reader.ReadToEnd(); reader.Close(); keysvals.Add("body", requestBody); - httpResponse.StatusCode = 200; - httpResponse.ContentType = "text/html"; - httpResponse.KeepAlive = false; - Hashtable responsedata = new Hashtable(); UUID agentID; diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs index 99523a1231..6bfc5cc4f2 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs @@ -477,7 +477,7 @@ namespace OpenSim.Services.Connectors.SimianGrid // Grab the asset data from the response stream using (MemoryStream stream = new MemoryStream()) { - responseStream.CopyTo(stream, 4096); + responseStream.CopyStream(stream, Int32.MaxValue); asset.Data = stream.ToArray(); } } diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 08a6194fb2..1f3cd0d554 100755 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -172,6 +172,7 @@ ;# {permissionmodules} {} {Permission modules to use (may specify multiple modules, separated by comma} {} DefaultPermissionsModule ;; Permission modules to use, separated by comma. + ;; Possible modules are DefaultPermissionsModule, PrimLimitsModule ; permissionmodules = DefaultPermissionsModule ;# {serverside_object_permissions} {permissionmodules:DefaultPermissionsModule} {Activate permission handling by the sim?} {true false} true @@ -790,11 +791,6 @@ ; Enabled = false -[PrimLimitsModule] - ;# {EnforcePrimLimits} {} {Enforce parcel prim limits} {true false} false - ;; Enable parcel prim limits. Off by default to emulate pre-existing behavior. - ; EnforcePrimLimits = false - [Architecture] ;# {Include-Architecture} {} {Choose one of the following architectures} {config-include/Standalone.ini config-include/StandaloneHypergrid.ini config-include/Grid.ini config-include/GridHypergrid.ini config-include/SimianGrid.ini config-include/HyperSimianGrid.ini} config-include/Standalone.ini