diff --git a/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureServerConnector.cs b/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureServerConnector.cs new file mode 100644 index 0000000000..10ea8eefe6 --- /dev/null +++ b/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureServerConnector.cs @@ -0,0 +1,76 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using Nini.Config; +using OpenSim.Server.Base; +using OpenSim.Services.Interfaces; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Server.Handlers.Base; +using OpenMetaverse; + +namespace OpenSim.Capabilities.Handlers +{ + public class UploadBakedTextureServerConnector : ServiceConnector + { + private IAssetService m_AssetService; + private string m_ConfigName = "CapsService"; + + public UploadBakedTextureServerConnector(IConfigSource config, IHttpServer server, string configName) : + base(config, server, configName) + { + if (configName != String.Empty) + m_ConfigName = configName; + + IConfig serverConfig = config.Configs[m_ConfigName]; + if (serverConfig == null) + throw new Exception(String.Format("No section '{0}' in config file", m_ConfigName)); + + string assetService = serverConfig.GetString("AssetService", String.Empty); + + if (assetService == String.Empty) + throw new Exception("No AssetService in config file"); + + Object[] args = new Object[] { config }; + m_AssetService = + ServerUtils.LoadPlugin(assetService, args); + + if (m_AssetService == null) + throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName)); + + // NEED TO FIX THIS + OpenSim.Framework.Capabilities.Caps caps = new OpenSim.Framework.Capabilities.Caps(server, "", server.Port, "", UUID.Zero, ""); + server.AddStreamHandler(new RestStreamHandler( + "POST", + "/CAPS/UploadBakedTexture/", + new UploadBakedTextureHandler(caps, m_AssetService, true).UploadBakedTexture, + "UploadBakedTexture", + "Upload Baked Texture Capability")); + + } + } +} \ No newline at end of file diff --git a/OpenSim/Data/IHGTravelingData.cs b/OpenSim/Data/IHGTravelingData.cs new file mode 100644 index 0000000000..452af7bc50 --- /dev/null +++ b/OpenSim/Data/IHGTravelingData.cs @@ -0,0 +1,59 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using OpenMetaverse; +using OpenSim.Framework; + +namespace OpenSim.Data +{ + // This MUST be a ref type! + public class HGTravelingData + { + public UUID SessionID; + public UUID UserID; + public Dictionary Data; + + public HGTravelingData() + { + Data = new Dictionary(); + } + } + + /// + /// An interface for connecting to the user grid datastore + /// + public interface IHGTravelingData + { + HGTravelingData Get(UUID sessionID); + HGTravelingData[] GetSessions(UUID userID); + bool Store(HGTravelingData data); + bool Delete(UUID sessionID); + void DeleteOld(); + } +} \ No newline at end of file diff --git a/OpenSim/Data/MySQL/MySQLHGTravelData.cs b/OpenSim/Data/MySQL/MySQLHGTravelData.cs new file mode 100644 index 0000000000..e81b880c95 --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLHGTravelData.cs @@ -0,0 +1,80 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Data; +using System.Reflection; +using System.Threading; +using log4net; +using OpenMetaverse; +using OpenSim.Framework; +using MySql.Data.MySqlClient; + +namespace OpenSim.Data.MySQL +{ + /// + /// A MySQL Interface for user grid data + /// + public class MySQLHGTravelData : MySQLGenericTableHandler, IHGTravelingData + { +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + public MySQLHGTravelData(string connectionString, string realm) : base(connectionString, realm, "HGTravelStore") { } + + public HGTravelingData Get(UUID sessionID) + { + HGTravelingData[] ret = Get("SessionID", sessionID.ToString()); + + if (ret.Length == 0) + return null; + + return ret[0]; + } + + public HGTravelingData[] GetSessions(UUID userID) + { + return base.Get("UserID", userID.ToString()); + } + + public bool Delete(UUID sessionID) + { + return Delete("SessionID", sessionID.ToString()); + } + + public void DeleteOld() + { + using (MySqlCommand cmd = new MySqlCommand()) + { + cmd.CommandText = String.Format("delete from {0} where TMStamp < NOW() - INTERVAL 2 DAY", m_Realm); + + ExecuteNonQuery(cmd); + } + + } + } +} \ No newline at end of file diff --git a/OpenSim/Data/MySQL/Resources/HGTravelStore.migrations b/OpenSim/Data/MySQL/Resources/HGTravelStore.migrations new file mode 100644 index 0000000000..b4e4422871 --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/HGTravelStore.migrations @@ -0,0 +1,18 @@ +:VERSION 1 # -------------------------- + +BEGIN; + +CREATE TABLE `hg_traveling_data` ( + `SessionID` VARCHAR(36) NOT NULL, + `UserID` VARCHAR(36) NOT NULL, + `GridExternalName` VARCHAR(255) NOT NULL DEFAULT '', + `ServiceToken` VARCHAR(255) NOT NULL DEFAULT '', + `ClientIPAddress` VARCHAR(16) NOT NULL DEFAULT '', + `MyIPAddress` VARCHAR(16) NOT NULL DEFAULT '', + `TMStamp` timestamp NOT NULL, + PRIMARY KEY (`SessionID`), + KEY (`UserID`) +) ENGINE=InnoDB; + +COMMIT; + diff --git a/OpenSim/Data/SQLite/Resources/HGTravelStore.migrations b/OpenSim/Data/SQLite/Resources/HGTravelStore.migrations new file mode 100644 index 0000000000..2e73caa9d2 --- /dev/null +++ b/OpenSim/Data/SQLite/Resources/HGTravelStore.migrations @@ -0,0 +1,18 @@ +:VERSION 1 # -------------------------- + +BEGIN; + +CREATE TABLE hg_traveling_data ( + SessionID VARCHAR(36) NOT NULL, + UserID VARCHAR(36) NOT NULL, + GridExternalName VARCHAR(255) NOT NULL DEFAULT '', + ServiceToken VARCHAR(255) NOT NULL DEFAULT '', + ClientIPAddress VARCHAR(16) NOT NULL DEFAULT '', + MyIPAddress VARCHAR(16) NOT NULL DEFAULT '', + TMStamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`SessionID`), + KEY (`UserID`) +) ENGINE=InnoDB; + +COMMIT; + diff --git a/OpenSim/Data/SQLite/SQLiteHGTravelData.cs b/OpenSim/Data/SQLite/SQLiteHGTravelData.cs new file mode 100644 index 0000000000..db288b2486 --- /dev/null +++ b/OpenSim/Data/SQLite/SQLiteHGTravelData.cs @@ -0,0 +1,82 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Data; +using System.Reflection; +using System.Threading; +using log4net; +using OpenMetaverse; +using OpenSim.Framework; +using Mono.Data.Sqlite; + +namespace OpenSim.Data.SQLite +{ + /// + /// A SQL Interface for user grid data + /// + public class SQLiteHGTravelData : SQLiteGenericTableHandler, IHGTravelingData + { +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + public SQLiteHGTravelData(string connectionString, string realm) + : base(connectionString, realm, "HGTravelStore") {} + + public HGTravelingData Get(UUID sessionID) + { + HGTravelingData[] ret = Get("SessionID", sessionID.ToString()); + + if (ret.Length == 0) + return null; + + return ret[0]; + } + + public HGTravelingData[] GetSessions(UUID userID) + { + return base.Get("UserID", userID.ToString()); + } + + public bool Delete(UUID sessionID) + { + return Delete("SessionID", sessionID.ToString()); + } + + public void DeleteOld() + { + using (SqliteCommand cmd = new SqliteCommand()) + { + cmd.CommandText = String.Format("delete from {0} where TMStamp < datetime('now', '-2 day') ", m_Realm); + + DoQuery(cmd); + } + + } + + } +} \ No newline at end of file diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs index dfe60aaff1..9fc048bcc9 100644 --- a/OpenSim/Framework/ChildAgentDataUpdate.cs +++ b/OpenSim/Framework/ChildAgentDataUpdate.cs @@ -171,9 +171,10 @@ namespace OpenSim.Framework /// Soon to be decommissioned /// /// - public void CopyFrom(ChildAgentDataUpdate cAgent) + public void CopyFrom(ChildAgentDataUpdate cAgent, UUID sid) { AgentID = new UUID(cAgent.AgentID); + SessionID = sid; // next: ??? Size = new Vector3(); diff --git a/OpenSim/Framework/Tests/MundaneFrameworkTests.cs b/OpenSim/Framework/Tests/MundaneFrameworkTests.cs index 1dc80533d8..3f0a031b33 100644 --- a/OpenSim/Framework/Tests/MundaneFrameworkTests.cs +++ b/OpenSim/Framework/Tests/MundaneFrameworkTests.cs @@ -100,7 +100,7 @@ namespace OpenSim.Framework.Tests cadu.AVHeight = Size1.Z; AgentPosition position2 = new AgentPosition(); - position2.CopyFrom(cadu); + position2.CopyFrom(cadu, position1.SessionID); Assert.IsTrue( position2.AgentID == position1.AgentID diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index cafe103135..8cfc4d4b86 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -2293,7 +2293,7 @@ namespace OpenSim.Framework { if (m_highQueue.Count > 0) res = m_highQueue.Dequeue(); - else + else if (m_lowQueue.Count > 0) res = m_lowQueue.Dequeue(); if (m_highQueue.Count == 0 && m_lowQueue.Count == 0) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs index 86a0298eb4..164adeb2d4 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs @@ -347,8 +347,9 @@ namespace OpenSim.Region.ClientStack.Linden aPollRequest poolreq = m_queue.Dequeue(); - poolreq.thepoll.Process(poolreq); + if (poolreq != null && poolreq.thepoll != null) + poolreq.thepoll.Process(poolreq); } } } -} \ No newline at end of file +} diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 2aab4f9839..85270a6e2d 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -1469,7 +1469,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(uccp.CircuitCode.Code); bool tp = (aCircuit.teleportFlags > 0); - // Let's delay this for TP agents, otherwise the viewer doesn't know where to get meshes from + // Let's delay this for TP agents, otherwise the viewer doesn't know where to get resources from if (!tp) client.SceneAgent.SendInitialDataToMe(); } diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 85d26f312a..344c8d7f46 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -817,7 +817,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Keeping avatar in source region.", sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); - Fail(sp, finalDestination, logout, "Connection between viewer and destination region could not be established."); + Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established."); return; } @@ -829,7 +829,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after UpdateAgent on client request", sp.Name, finalDestination.RegionName, sp.Scene.Name); - CleanupFailedInterRegionTeleport(sp, finalDestination); + CleanupFailedInterRegionTeleport(sp, currentAgentCircuit.SessionID.ToString(), finalDestination); return; } @@ -873,7 +873,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); - Fail(sp, finalDestination, logout, "Destination region did not signal teleport completion."); + Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Destination region did not signal teleport completion."); return; } @@ -927,7 +927,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer /// /// /// - protected virtual void CleanupFailedInterRegionTeleport(ScenePresence sp, GridRegion finalDestination) + protected virtual void CleanupFailedInterRegionTeleport(ScenePresence sp, string auth_token, GridRegion finalDestination) { m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); @@ -938,7 +938,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // Finally, kill the agent we just created at the destination. // XXX: Possibly this should be done asynchronously. - Scene.SimulationService.CloseAgent(finalDestination, sp.UUID); + Scene.SimulationService.CloseAgent(finalDestination, sp.UUID, auth_token); } /// @@ -948,9 +948,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer /// /// /// Human readable reason for teleport failure. Will be sent to client. - protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout, string reason) + protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout, string auth_code, string reason) { - CleanupFailedInterRegionTeleport(sp, finalDestination); + CleanupFailedInterRegionTeleport(sp, auth_code, finalDestination); m_interRegionTeleportFailures.Value++; diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 759155a799..76dbc72270 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -207,6 +207,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { m_GatekeeperConnector = new GatekeeperServiceConnector(scene.AssetService); m_UAS = scene.RequestModuleInterface(); + if (m_UAS == null) + m_UAS = new UserAgentServiceConnector(m_ThisHomeURI); + } } @@ -573,12 +576,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (uMan != null && uMan.IsLocalGridUser(obj.AgentId)) { // local grid user + m_UAS.LogoutAgent(obj.AgentId, obj.SessionId); return; } AgentCircuitData aCircuit = ((Scene)(obj.Scene)).AuthenticateHandler.GetAgentCircuitData(obj.CircuitCode); - - if (aCircuit.ServiceURLs.ContainsKey("HomeURI")) + if (aCircuit != null && aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("HomeURI")) { string url = aCircuit.ServiceURLs["HomeURI"].ToString(); IUserAgentService security = new UserAgentServiceConnector(url); diff --git a/OpenSim/Region/CoreModules/Framework/GridServiceThrottle/GridServiceThrottleModule.cs b/OpenSim/Region/CoreModules/Framework/GridServiceThrottle/GridServiceThrottleModule.cs index f1eb1ad3a9..fd4d48ae2b 100644 --- a/OpenSim/Region/CoreModules/Framework/GridServiceThrottle/GridServiceThrottleModule.cs +++ b/OpenSim/Region/CoreModules/Framework/GridServiceThrottle/GridServiceThrottleModule.cs @@ -140,11 +140,13 @@ namespace OpenSim.Region.CoreModules.Framework Watchdog.UpdateThread(); GridRegionRequest request = m_RequestQueue.Dequeue(); - GridRegion r = m_scenes[0].GridService.GetRegionByUUID(UUID.Zero, request.regionID); - - if (r != null && r.RegionHandle != 0) - request.client.SendRegionHandle(request.regionID, r.RegionHandle); + if (request != null) + { + GridRegion r = m_scenes[0].GridService.GetRegionByUUID(UUID.Zero, request.regionID); + if (r != null && r.RegionHandle != 0) + request.client.SendRegionHandle(request.regionID, r.RegionHandle); + } } } } diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index a5280939fc..507329eb59 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs @@ -681,17 +681,19 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement Watchdog.UpdateThread(); NameRequest request = m_RequestQueue.Dequeue(); - string[] names; - bool foundRealName = TryGetUserNames(request.uuid, out names); - - if (names.Length == 2) + if (request != null) { - if (!foundRealName) - m_log.DebugFormat("[USER MANAGEMENT MODULE]: Sending {0} {1} for {2} to {3} since no bound name found", names[0], names[1], request.uuid, request.client.Name); + string[] names; + bool foundRealName = TryGetUserNames(request.uuid, out names); - request.client.SendNameReply(request.uuid, names[0], names[1]); + if (names.Length == 2) + { + if (!foundRealName) + m_log.DebugFormat("[USER MANAGEMENT MODULE]: Sending {0} {1} for {2} to {3} since no bound name found", names[0], names[1], request.uuid, request.client.Name); + + request.client.SendNameReply(request.uuid, names[0], names[1]); + } } - } } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs index 942796171c..6d5039b6fe 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs @@ -250,26 +250,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation return true; } - public bool RetrieveAgent(GridRegion destination, UUID id, out IAgentData agent) - { - agent = null; - - if (destination == null) - return false; - - if (m_scenes.ContainsKey(destination.RegionID)) - { -// m_log.DebugFormat( -// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", -// s.RegionInfo.RegionName, destination.RegionHandle); - - return m_scenes[destination.RegionID].IncomingRetrieveRootAgent(id, out agent); - } - - //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate"); - return false; - } - public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason) { reason = "Communications failure"; @@ -306,7 +286,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation return false; } - public bool CloseAgent(GridRegion destination, UUID id) + public bool CloseAgent(GridRegion destination, UUID id, string auth_token) { if (destination == null) return false; @@ -317,7 +297,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation // "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", // s.RegionInfo.RegionName, destination.RegionHandle); - m_scenes[destination.RegionID].IncomingCloseAgent(id, false); + m_scenes[destination.RegionID].IncomingCloseAgent(id, false, auth_token); return true; } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs index d120e11c2c..8722b80ced 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs @@ -212,24 +212,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation return m_remoteConnector.UpdateAgent(destination, cAgentData); } - public bool RetrieveAgent(GridRegion destination, UUID id, out IAgentData agent) - { - agent = null; - - if (destination == null) - return false; - - // Try local first - if (m_localBackend.RetrieveAgent(destination, id, out agent)) - return true; - - // else do the remote thing - if (!m_localBackend.IsLocalRegion(destination.RegionID)) - return m_remoteConnector.RetrieveAgent(destination, id, out agent); - - return false; - } - public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason) { reason = "Communications failure"; @@ -263,18 +245,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation } - public bool CloseAgent(GridRegion destination, UUID id) + public bool CloseAgent(GridRegion destination, UUID id, string auth_token) { if (destination == null) return false; // Try local first - if (m_localBackend.CloseAgent(destination, id)) + if (m_localBackend.CloseAgent(destination, id, auth_token)) return true; // else do the remote thing if (!m_localBackend.IsLocalRegion(destination.RegionID)) - return m_remoteConnector.CloseAgent(destination, id); + return m_remoteConnector.CloseAgent(destination, id, auth_token); return false; } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 54956ee3bf..9cfe869098 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3452,7 +3452,7 @@ namespace OpenSim.Region.Framework.Scenes regions.Remove(RegionInfo.RegionHandle); // This ends up being done asynchronously so that a logout isn't held up where there are many present but unresponsive neighbours. - m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); + m_sceneGridService.SendCloseChildAgentConnections(agentID, acd.SessionID.ToString(), regions); } m_eventManager.TriggerClientClosed(agentID, this); @@ -4202,10 +4202,16 @@ namespace OpenSim.Region.Framework.Scenes if (childAgentUpdate != null) { + if (cAgentData.SessionID != childAgentUpdate.ControllingClient.SessionId) + { + m_log.WarnFormat("[SCENE]: Attempt to update agent {0} with invalid session id {1} (possibly from simulator in older version; tell them to update).", childAgentUpdate.UUID, cAgentData.SessionID); + Console.WriteLine(String.Format("[SCENE]: Attempt to update agent {0} ({1}) with invalid session id {2}", + childAgentUpdate.UUID, childAgentUpdate.ControllingClient.SessionId, cAgentData.SessionID)); + } + childAgentUpdate.ChildAgentDataUpdate(cAgentData); return true; } - return false; } @@ -4221,20 +4227,24 @@ namespace OpenSim.Region.Framework.Scenes ScenePresence childAgentUpdate = GetScenePresence(cAgentData.AgentID); if (childAgentUpdate != null) { - // I can't imagine *yet* why we would get an update if the agent is a root agent.. - // however to avoid a race condition crossing borders.. - if (childAgentUpdate.IsChildAgent) + if (childAgentUpdate.ControllingClient.SessionId == cAgentData.SessionID) { - uint rRegionX = (uint)(cAgentData.RegionHandle >> 40); - uint rRegionY = (((uint)(cAgentData.RegionHandle)) >> 8); - uint tRegionX = RegionInfo.RegionLocX; - uint tRegionY = RegionInfo.RegionLocY; - //Send Data to ScenePresence - childAgentUpdate.ChildAgentDataUpdate(cAgentData, tRegionX, tRegionY, rRegionX, rRegionY); - // Not Implemented: - //TODO: Do we need to pass the message on to one of our neighbors? + // I can't imagine *yet* why we would get an update if the agent is a root agent.. + // however to avoid a race condition crossing borders.. + if (childAgentUpdate.IsChildAgent) + { + uint rRegionX = (uint)(cAgentData.RegionHandle >> 40); + uint rRegionY = (((uint)(cAgentData.RegionHandle)) >> 8); + uint tRegionX = RegionInfo.RegionLocX; + uint tRegionY = RegionInfo.RegionLocY; + //Send Data to ScenePresence + childAgentUpdate.ChildAgentDataUpdate(cAgentData, tRegionX, tRegionY, rRegionX, rRegionY); + // Not Implemented: + //TODO: Do we need to pass the message on to one of our neighbors? + } } - + else + m_log.WarnFormat("[SCENE]: Attempt at updating position of agent {0} with invalid session id {1}", childAgentUpdate.UUID, cAgentData.SessionID); return true; } @@ -4277,6 +4287,25 @@ namespace OpenSim.Region.Framework.Scenes return false; } + /// + /// Authenticated close (via network) + /// + /// + /// + /// + /// + public bool IncomingCloseAgent(UUID agentID, bool force, string auth_token) + { + //m_log.DebugFormat("[SCENE]: Processing incoming close agent {0} in region {1} with auth_token {2}", agentID, RegionInfo.RegionName, auth_token); + + // Check that the auth_token is valid + AgentCircuitData acd = AuthenticateHandler.GetAgentCircuitData(agentID); + if (acd != null && acd.SessionID.ToString() == auth_token) + return IncomingCloseAgent(agentID, force); + else + m_log.ErrorFormat("[SCENE]: Request to close agent {0} with invalid authorization token {1}", agentID, auth_token); + return false; + } /// /// Tell a single agent to disconnect from the region. @@ -4289,7 +4318,6 @@ namespace OpenSim.Region.Framework.Scenes public bool IncomingCloseAgent(UUID agentID, bool force) { //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); - ScenePresence presence = m_sceneGraph.GetScenePresence(agentID); if (presence != null) { @@ -4297,7 +4325,7 @@ namespace OpenSim.Region.Framework.Scenes return true; } - // Agent not here + // Agent not here return false; } diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs index 8238e23f9c..77889fadad 100644 --- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs @@ -197,7 +197,7 @@ namespace OpenSim.Region.Framework.Scenes /// /// Closes a child agent on a given region /// - protected void SendCloseChildAgent(UUID agentID, ulong regionHandle) + protected void SendCloseChildAgent(UUID agentID, ulong regionHandle, string auth_token) { // let's do our best, but there's not much we can do if the neighbour doesn't accept. @@ -210,7 +210,7 @@ namespace OpenSim.Region.Framework.Scenes m_log.DebugFormat( "[SCENE COMMUNICATION SERVICE]: Sending close agent ID {0} to {1}", agentID, destination.RegionName); - m_scene.SimulationService.CloseAgent(destination, agentID); + m_scene.SimulationService.CloseAgent(destination, agentID, auth_token); } /// @@ -219,14 +219,14 @@ namespace OpenSim.Region.Framework.Scenes /// /// /// - public void SendCloseChildAgentConnections(UUID agentID, List regionslst) + public void SendCloseChildAgentConnections(UUID agentID, string auth_code, List regionslst) { foreach (ulong handle in regionslst) { // We must take a copy here since handle is acts like a reference when used in an iterator. // This leads to race conditions if directly passed to SendCloseChildAgent with more than one neighbour region. ulong handleCopy = handle; - Util.FireAndForget((o) => { SendCloseChildAgent(agentID, handleCopy); }); + Util.FireAndForget((o) => { SendCloseChildAgent(agentID, handleCopy, auth_code); }); } } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 774546c693..990ef6e20b 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1010,7 +1010,9 @@ namespace OpenSim.Region.Framework.Scenes // recorded, which stops the input from being processed. MovementFlag = 0; - m_scene.EventManager.TriggerOnMakeRootAgent(this); + // DIVA NOTE: I moved TriggerOnMakeRootAgent out of here and into the end of + // CompleteMovement. We don't want modules doing heavy computation before CompleteMovement + // is over. } public int GetStateSource() @@ -1327,10 +1329,15 @@ namespace OpenSim.Region.Framework.Scenes bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); MakeRootAgent(AbsolutePosition, flying); ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); + // Remember in HandleUseCircuitCode, we delayed this to here + // This will also send the initial data to clients when TP to a neighboring region. + // Not ideal, but until we know we're TP-ing from a neighboring region, there's not much we can do + if (m_teleportFlags > 0) + SendInitialDataToMe(); // m_log.DebugFormat("[SCENE PRESENCE] Completed movement"); - if ((m_callbackURI != null) && !m_callbackURI.Equals("")) + if (!string.IsNullOrEmpty(m_callbackURI)) { // We cannot sleep here since this would hold up the inbound packet processing thread, as // CompleteMovement() is executed synchronously. However, it might be better to delay the release @@ -1358,9 +1365,6 @@ namespace OpenSim.Region.Framework.Scenes // Create child agents in neighbouring regions if (openChildAgents && !IsChildAgent) { - // Remember in HandleUseCircuitCode, we delayed this to here - SendInitialDataToMe(); - IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface(); if (m_agentTransfer != null) Util.FireAndForget(delegate { m_agentTransfer.EnableChildAgents(this); }); @@ -1382,6 +1386,11 @@ namespace OpenSim.Region.Framework.Scenes // m_log.DebugFormat( // "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms", // client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds); + + // DIVA NOTE: moved this here from MakeRoot. We don't want modules making heavy + // computations before CompleteMovement is over + m_scene.EventManager.TriggerOnMakeRootAgent(this); + } /// @@ -2689,11 +2698,12 @@ namespace OpenSim.Region.Framework.Scenes SendOtherAgentsAppearanceToMe(); EntityBase[] entities = Scene.Entities.GetEntities(); - foreach(EntityBase e in entities) + foreach (EntityBase e in entities) { if (e != null && e is SceneObjectGroup) ((SceneObjectGroup)e).SendFullUpdateToClient(ControllingClient); } + }); } @@ -2917,7 +2927,7 @@ namespace OpenSim.Region.Framework.Scenes cadu.Velocity = Velocity; AgentPosition agentpos = new AgentPosition(); - agentpos.CopyFrom(cadu); + agentpos.CopyFrom(cadu, ControllingClient.SessionId); // Let's get this out of the update loop Util.FireAndForget(delegate { m_scene.SendOutChildAgentUpdates(agentpos, this); }); @@ -3155,7 +3165,11 @@ namespace OpenSim.Region.Framework.Scenes { m_log.Debug("[SCENE PRESENCE]: Closing " + byebyeRegions.Count + " child agents"); - m_scene.SceneGridService.SendCloseChildAgentConnections(ControllingClient.AgentId, byebyeRegions); + AgentCircuitData acd = Scene.AuthenticateHandler.GetAgentCircuitData(UUID); + string auth = string.Empty; + if (acd != null) + auth = acd.SessionID.ToString(); + m_scene.SceneGridService.SendCloseChildAgentConnections(ControllingClient.AgentId, auth, byebyeRegions); } foreach (ulong handle in byebyeRegions) @@ -3252,6 +3266,7 @@ namespace OpenSim.Region.Framework.Scenes cAgent.AgentID = UUID; cAgent.RegionID = Scene.RegionInfo.RegionID; + cAgent.SessionID = ControllingClient.SessionId; cAgent.Position = AbsolutePosition; cAgent.Velocity = m_velocity; diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs index 5a722398e2..5df9aba0f2 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs @@ -112,6 +112,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests //moveArgs.BodyRotation = Quaternion.CreateFromEulers(Vector3.Zero); moveArgs.BodyRotation = Quaternion.CreateFromEulers(new Vector3(0, 0, (float)-(Math.PI / 2))); moveArgs.ControlFlags = (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS; + moveArgs.SessionID = acd.SessionID; originalSp.HandleAgentUpdate(originalSp.ControllingClient, moveArgs); diff --git a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs index 40a34c658a..4ac477f692 100644 --- a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs +++ b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs @@ -27,11 +27,13 @@ using System; using System.Collections; +using System.Collections.Specialized; using System.IO; using System.IO.Compression; using System.Reflection; using System.Net; using System.Text; +using System.Web; using OpenSim.Server.Base; using OpenSim.Server.Handlers.Base; @@ -90,14 +92,13 @@ namespace OpenSim.Server.Handlers.Simulation // Next, let's parse the verb string method = (string)request["http-method"]; - if (method.Equals("GET")) + if (method.Equals("DELETE")) { - DoAgentGet(request, responsedata, agentID, regionID); - return responsedata; - } - else if (method.Equals("DELETE")) - { - DoAgentDelete(request, responsedata, agentID, action, regionID); + string auth_token = string.Empty; + if (request.ContainsKey("auth")) + auth_token = request["auth"].ToString(); + + DoAgentDelete(request, responsedata, agentID, action, regionID, auth_token); return responsedata; } else if (method.Equals("QUERYACCESS")) @@ -107,7 +108,7 @@ namespace OpenSim.Server.Handlers.Simulation } else { - m_log.InfoFormat("[AGENT HANDLER]: method {0} not supported in agent message (caller is {1})", method, Util.GetCallerIP(request)); + m_log.ErrorFormat("[AGENT HANDLER]: method {0} not supported in agent message {1} (caller is {2})", method, (string)request["uri"], Util.GetCallerIP(request)); responsedata["int_response_code"] = HttpStatusCode.MethodNotAllowed; responsedata["str_response_string"] = "Method not allowed"; @@ -156,61 +157,12 @@ namespace OpenSim.Server.Handlers.Simulation // Console.WriteLine("str_response_string [{0}]", responsedata["str_response_string"]); } - protected virtual void DoAgentGet(Hashtable request, Hashtable responsedata, UUID id, UUID regionID) + protected void DoAgentDelete(Hashtable request, Hashtable responsedata, UUID id, string action, UUID regionID, string auth_token) { - if (m_SimulationService == null) - { - m_log.Debug("[AGENT HANDLER]: Agent GET called. Harmless but useless."); - responsedata["content_type"] = "application/json"; - responsedata["int_response_code"] = HttpStatusCode.NotImplemented; - responsedata["str_response_string"] = string.Empty; - - return; - } - - GridRegion destination = new GridRegion(); - destination.RegionID = regionID; - - IAgentData agent = null; - bool result = m_SimulationService.RetrieveAgent(destination, id, out agent); - OSDMap map = null; - if (result) - { - if (agent != null) // just to make sure - { - map = agent.Pack(); - string strBuffer = ""; - try - { - strBuffer = OSDParser.SerializeJsonString(map); - } - catch (Exception e) - { - m_log.WarnFormat("[AGENT HANDLER]: Exception thrown on serialization of DoAgentGet: {0}", e.Message); - responsedata["int_response_code"] = HttpStatusCode.InternalServerError; - // ignore. buffer will be empty, caller should check. - } - - responsedata["content_type"] = "application/json"; - responsedata["int_response_code"] = HttpStatusCode.OK; - responsedata["str_response_string"] = strBuffer; - } - else - { - responsedata["int_response_code"] = HttpStatusCode.InternalServerError; - responsedata["str_response_string"] = "Internal error"; - } - } + if (string.IsNullOrEmpty(action)) + m_log.DebugFormat("[AGENT HANDLER]: >>> DELETE <<< RegionID: {0}; from: {1}; auth_code: {2}", regionID, Util.GetCallerIP(request), auth_token); else - { - responsedata["int_response_code"] = HttpStatusCode.NotFound; - responsedata["str_response_string"] = "Not Found"; - } - } - - protected void DoAgentDelete(Hashtable request, Hashtable responsedata, UUID id, string action, UUID regionID) - { - m_log.Debug(" >>> DoDelete action:" + action + "; RegionID:" + regionID); + m_log.DebugFormat("[AGENT HANDLER]: Release {0} to RegionID: {1}", id, regionID); GridRegion destination = new GridRegion(); destination.RegionID = regionID; @@ -218,12 +170,12 @@ namespace OpenSim.Server.Handlers.Simulation if (action.Equals("release")) ReleaseAgent(regionID, id); else - Util.FireAndForget(delegate { m_SimulationService.CloseAgent(destination, id); }); + Util.FireAndForget(delegate { m_SimulationService.CloseAgent(destination, id, auth_token); }); responsedata["int_response_code"] = HttpStatusCode.OK; responsedata["str_response_string"] = "OpenSim agent " + id.ToString(); - m_log.DebugFormat("[AGENT HANDLER]: Agent {0} Released/Deleted from region {1}", id, regionID); + //m_log.DebugFormat("[AGENT HANDLER]: Agent {0} Released/Deleted from region {1}", id, regionID); } protected virtual void ReleaseAgent(UUID regionID, UUID id) diff --git a/OpenSim/Services/Connectors/GridUser/GridUserServicesConnector.cs b/OpenSim/Services/Connectors/GridUser/GridUserServicesConnector.cs index 94bda82d14..1a62d2f1e7 100644 --- a/OpenSim/Services/Connectors/GridUser/GridUserServicesConnector.cs +++ b/OpenSim/Services/Connectors/GridUser/GridUserServicesConnector.cs @@ -214,7 +214,7 @@ namespace OpenSim.Services.Connectors } else - m_log.DebugFormat("[GRID USER CONNECTOR]: Loggedin received empty reply"); + m_log.DebugFormat("[GRID USER CONNECTOR]: Get received empty reply"); } catch (Exception e) { diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs index f51c809413..aca414b82c 100644 --- a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs +++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs @@ -271,41 +271,6 @@ namespace OpenSim.Services.Connectors.Simulation return false; } - /// - /// Not sure what sequence causes this function to be invoked. The only calling - /// path is through the GET method - /// - public bool RetrieveAgent(GridRegion destination, UUID id, out IAgentData agent) - { - // m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: RetrieveAgent start"); - - agent = null; - - // Eventually, we want to use a caps url instead of the agentID - string uri = destination.ServerURI + AgentPath() + id + "/" + destination.RegionID.ToString() + "/"; - - try - { - OSDMap result = WebUtil.GetFromService(uri, 10000); - if (result["Success"].AsBoolean()) - { - // OSDMap args = Util.GetOSDMap(result["_RawResult"].AsString()); - OSDMap args = (OSDMap)result["_Result"]; - if (args != null) - { - agent = new CompleteAgentData(); - agent.Unpack(args, null); - return true; - } - } - } - catch (Exception e) - { - m_log.Warn("[REMOTE SIMULATION CONNECTOR]: UpdateAgent failed with exception: " + e.ToString()); - } - - return false; - } /// /// @@ -402,11 +367,10 @@ namespace OpenSim.Services.Connectors.Simulation /// /// - public bool CloseAgent(GridRegion destination, UUID id) + public bool CloseAgent(GridRegion destination, UUID id, string auth_code) { -// m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: CloseAgent start"); - - string uri = destination.ServerURI + AgentPath() + id + "/" + destination.RegionID.ToString() + "/"; + string uri = destination.ServerURI + AgentPath() + id + "/" + destination.RegionID.ToString() + "/?auth=" + auth_code; + m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: CloseAgent {0}", uri); try { diff --git a/OpenSim/Services/HypergridService/GatekeeperService.cs b/OpenSim/Services/HypergridService/GatekeeperService.cs index 0cf1c14daa..0a3e70b5d5 100644 --- a/OpenSim/Services/HypergridService/GatekeeperService.cs +++ b/OpenSim/Services/HypergridService/GatekeeperService.cs @@ -419,6 +419,12 @@ namespace OpenSim.Services.HypergridService if (!CheckAddress(aCircuit.ServiceSessionID)) return false; + if (string.IsNullOrEmpty(aCircuit.IPAddress)) + { + m_log.DebugFormat("[GATEKEEPER SERVICE]: Agent did not provide a client IP address."); + return false; + } + string userURL = string.Empty; if (aCircuit.ServiceURLs.ContainsKey("HomeURI")) userURL = aCircuit.ServiceURLs["HomeURI"].ToString(); diff --git a/OpenSim/Services/HypergridService/UserAgentService.cs b/OpenSim/Services/HypergridService/UserAgentService.cs index 733993fb04..b414aca7fe 100644 --- a/OpenSim/Services/HypergridService/UserAgentService.cs +++ b/OpenSim/Services/HypergridService/UserAgentService.cs @@ -30,6 +30,7 @@ using System.Collections.Generic; using System.Net; using System.Reflection; +using OpenSim.Data; using OpenSim.Framework; using OpenSim.Services.Connectors.Friends; using OpenSim.Services.Connectors.Hypergrid; @@ -50,14 +51,14 @@ namespace OpenSim.Services.HypergridService /// needs to do it for them. /// Once we have better clients, this shouldn't be needed. /// - public class UserAgentService : IUserAgentService + public class UserAgentService : UserAgentServiceBase, IUserAgentService { private static readonly ILog m_log = LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType); // This will need to go into a DB table - static Dictionary m_TravelingAgents = new Dictionary(); + //static Dictionary m_Database = new Dictionary(); static bool m_Initialized = false; @@ -86,6 +87,7 @@ namespace OpenSim.Services.HypergridService } public UserAgentService(IConfigSource config, IFriendsSimConnector friendsConnector) + : base(config) { // Let's set this always, because we don't know the sequence // of instantiations @@ -146,6 +148,9 @@ namespace OpenSim.Services.HypergridService if (!m_GridName.EndsWith("/")) m_GridName = m_GridName + "/"; + // Finally some cleanup + m_Database.DeleteOld(); + } } @@ -260,7 +265,8 @@ namespace OpenSim.Services.HypergridService // Generate a new service session agentCircuit.ServiceSessionID = region.ServerURI + ";" + UUID.Random(); - TravelingAgentInfo old = UpdateTravelInfo(agentCircuit, region); + TravelingAgentInfo old = null; + TravelingAgentInfo travel = CreateTravelInfo(agentCircuit, region, fromLogin, out old); bool success = false; string myExternalIP = string.Empty; @@ -282,23 +288,21 @@ namespace OpenSim.Services.HypergridService m_log.DebugFormat("[USER AGENT SERVICE]: Unable to login user {0} {1} to grid {2}, reason: {3}", agentCircuit.firstname, agentCircuit.lastname, region.ServerURI, reason); - // restore the old travel info - lock (m_TravelingAgents) - { - if (old == null) - m_TravelingAgents.Remove(agentCircuit.SessionID); - else - m_TravelingAgents[agentCircuit.SessionID] = old; - } + if (old != null) + StoreTravelInfo(old); + else + m_Database.Delete(agentCircuit.SessionID); return false; } + // Everything is ok + + // Update the perceived IP Address of our grid m_log.DebugFormat("[USER AGENT SERVICE]: Gatekeeper sees me as {0}", myExternalIP); - // else set the IP addresses associated with this client - if (fromLogin) - m_TravelingAgents[agentCircuit.SessionID].ClientIPAddress = agentCircuit.IPAddress; - m_TravelingAgents[agentCircuit.SessionID].MyIpAddress = myExternalIP; + travel.MyIpAddress = myExternalIP; + + StoreTravelInfo(travel); return true; } @@ -309,57 +313,39 @@ namespace OpenSim.Services.HypergridService return LoginAgentToGrid(agentCircuit, gatekeeper, finalDestination, false, out reason); } - private void SetClientIP(UUID sessionID, string ip) + TravelingAgentInfo CreateTravelInfo(AgentCircuitData agentCircuit, GridRegion region, bool fromLogin, out TravelingAgentInfo existing) { - if (m_TravelingAgents.ContainsKey(sessionID)) + HGTravelingData hgt = m_Database.Get(agentCircuit.SessionID); + existing = null; + + if (hgt != null) { - m_log.DebugFormat("[USER AGENT SERVICE]: Setting IP {0} for session {1}", ip, sessionID); - m_TravelingAgents[sessionID].ClientIPAddress = ip; + // Very important! Override whatever this agent comes with. + // UserAgentService always sets the IP for every new agent + // with the original IP address. + existing = new TravelingAgentInfo(hgt); + agentCircuit.IPAddress = existing.ClientIPAddress; } - } - TravelingAgentInfo UpdateTravelInfo(AgentCircuitData agentCircuit, GridRegion region) - { - TravelingAgentInfo travel = new TravelingAgentInfo(); - TravelingAgentInfo old = null; - lock (m_TravelingAgents) - { - if (m_TravelingAgents.ContainsKey(agentCircuit.SessionID)) - { - // Very important! Override whatever this agent comes with. - // UserAgentService always sets the IP for every new agent - // with the original IP address. - agentCircuit.IPAddress = m_TravelingAgents[agentCircuit.SessionID].ClientIPAddress; - - old = m_TravelingAgents[agentCircuit.SessionID]; - } - - m_TravelingAgents[agentCircuit.SessionID] = travel; - } + TravelingAgentInfo travel = new TravelingAgentInfo(existing); + travel.SessionID = agentCircuit.SessionID; travel.UserID = agentCircuit.AgentID; travel.GridExternalName = region.ServerURI; travel.ServiceToken = agentCircuit.ServiceSessionID; - if (old != null) - travel.ClientIPAddress = old.ClientIPAddress; - return old; + if (fromLogin) + travel.ClientIPAddress = agentCircuit.IPAddress; + + StoreTravelInfo(travel); + + return travel; } public void LogoutAgent(UUID userID, UUID sessionID) { m_log.DebugFormat("[USER AGENT SERVICE]: User {0} logged out", userID); - lock (m_TravelingAgents) - { - List travels = new List(); - foreach (KeyValuePair kvp in m_TravelingAgents) - if (kvp.Value == null) // do some clean up - travels.Add(kvp.Key); - else if (kvp.Value.UserID == userID) - travels.Add(kvp.Key); - foreach (UUID session in travels) - m_TravelingAgents.Remove(session); - } + m_Database.Delete(sessionID); GridUserInfo guinfo = m_GridUserService.GetGridUserInfo(userID.ToString()); if (guinfo != null) @@ -369,10 +355,11 @@ namespace OpenSim.Services.HypergridService // We need to prevent foreign users with the same UUID as a local user public bool IsAgentComingHome(UUID sessionID, string thisGridExternalName) { - if (!m_TravelingAgents.ContainsKey(sessionID)) + HGTravelingData hgt = m_Database.Get(sessionID); + if (hgt == null) return false; - TravelingAgentInfo travel = m_TravelingAgents[sessionID]; + TravelingAgentInfo travel = new TravelingAgentInfo(hgt); return travel.GridExternalName.ToLower() == thisGridExternalName.ToLower(); } @@ -385,31 +372,32 @@ namespace OpenSim.Services.HypergridService m_log.DebugFormat("[USER AGENT SERVICE]: Verifying Client session {0} with reported IP {1}.", sessionID, reportedIP); - if (m_TravelingAgents.ContainsKey(sessionID)) - { - bool result = m_TravelingAgents[sessionID].ClientIPAddress == reportedIP || - m_TravelingAgents[sessionID].MyIpAddress == reportedIP; // NATed + HGTravelingData hgt = m_Database.Get(sessionID); + if (hgt == null) + return false; - m_log.DebugFormat("[USER AGENT SERVICE]: Comparing {0} with login IP {1} and MyIP {1}; result is {3}", - reportedIP, m_TravelingAgents[sessionID].ClientIPAddress, m_TravelingAgents[sessionID].MyIpAddress, result); + TravelingAgentInfo travel = new TravelingAgentInfo(hgt); - return result; - } + bool result = travel.ClientIPAddress == reportedIP || travel.MyIpAddress == reportedIP; // NATed - return false; + m_log.DebugFormat("[USER AGENT SERVICE]: Comparing {0} with login IP {1} and MyIP {1}; result is {3}", + reportedIP, travel.ClientIPAddress, travel.MyIpAddress, result); + + return result; } public bool VerifyAgent(UUID sessionID, string token) { - if (m_TravelingAgents.ContainsKey(sessionID)) + HGTravelingData hgt = m_Database.Get(sessionID); + if (hgt == null) { - m_log.DebugFormat("[USER AGENT SERVICE]: Verifying agent token {0} against {1}", token, m_TravelingAgents[sessionID].ServiceToken); - return m_TravelingAgents[sessionID].ServiceToken == token; + m_log.DebugFormat("[USER AGENT SERVICE]: Token verification for session {0}: no such session", sessionID); + return false; } - m_log.DebugFormat("[USER AGENT SERVICE]: Token verification for session {0}: no such session", sessionID); - - return false; + TravelingAgentInfo travel = new TravelingAgentInfo(hgt); + m_log.DebugFormat("[USER AGENT SERVICE]: Verifying agent token {0} against {1}", token, travel.ServiceToken); + return travel.ServiceToken == token; } [Obsolete] @@ -472,17 +460,17 @@ namespace OpenSim.Services.HypergridService } } - // Lastly, let's notify the rest who may be online somewhere else - foreach (string user in usersToBeNotified) - { - UUID id = new UUID(user); - if (m_TravelingAgents.ContainsKey(id) && m_TravelingAgents[id].GridExternalName != m_GridName) - { - string url = m_TravelingAgents[id].GridExternalName; - // forward - m_log.WarnFormat("[USER AGENT SERVICE]: User {0} is visiting {1}. HG Status notifications still not implemented.", user, url); - } - } + //// Lastly, let's notify the rest who may be online somewhere else + //foreach (string user in usersToBeNotified) + //{ + // UUID id = new UUID(user); + // if (m_Database.ContainsKey(id) && m_Database[id].GridExternalName != m_GridName) + // { + // string url = m_Database[id].GridExternalName; + // // forward + // m_log.WarnFormat("[USER AGENT SERVICE]: User {0} is visiting {1}. HG Status notifications still not implemented.", user, url); + // } + //} // and finally, let's send the online friends if (online) @@ -609,16 +597,13 @@ namespace OpenSim.Services.HypergridService public string LocateUser(UUID userID) { - foreach (TravelingAgentInfo t in m_TravelingAgents.Values) - { - if (t == null) - { - m_log.ErrorFormat("[USER AGENT SERVICE]: Oops! Null TravelingAgentInfo. Please report this on mantis"); - continue; - } - if (t.UserID == userID && !m_GridName.Equals(t.GridExternalName)) - return t.GridExternalName; - } + HGTravelingData[] hgts = m_Database.GetSessions(userID); + if (hgts == null) + return string.Empty; + + foreach (HGTravelingData t in hgts) + if (t.Data.ContainsKey("GridExternalName") && !m_GridName.Equals(t.Data["GridExternalName"])) + return t.Data["GridExternalName"]; return string.Empty; } @@ -689,17 +674,60 @@ namespace OpenSim.Services.HypergridService return exception; } + private void StoreTravelInfo(TravelingAgentInfo travel) + { + if (travel == null) + return; + + HGTravelingData hgt = new HGTravelingData(); + hgt.SessionID = travel.SessionID; + hgt.UserID = travel.UserID; + hgt.Data = new Dictionary(); + hgt.Data["GridExternalName"] = travel.GridExternalName; + hgt.Data["ServiceToken"] = travel.ServiceToken; + hgt.Data["ClientIPAddress"] = travel.ClientIPAddress; + hgt.Data["MyIPAddress"] = travel.MyIpAddress; + + m_Database.Store(hgt); + } #endregion } class TravelingAgentInfo { + public UUID SessionID; public UUID UserID; public string GridExternalName = string.Empty; public string ServiceToken = string.Empty; public string ClientIPAddress = string.Empty; // as seen from this user agent service public string MyIpAddress = string.Empty; // the user agent service's external IP, as seen from the next gatekeeper + + public TravelingAgentInfo(HGTravelingData t) + { + if (t.Data != null) + { + SessionID = new UUID(t.SessionID); + UserID = new UUID(t.UserID); + GridExternalName = t.Data["GridExternalName"]; + ServiceToken = t.Data["ServiceToken"]; + ClientIPAddress = t.Data["ClientIPAddress"]; + MyIpAddress = t.Data["MyIPAddress"]; + } + } + + public TravelingAgentInfo(TravelingAgentInfo old) + { + if (old != null) + { + SessionID = old.SessionID; + UserID = old.UserID; + GridExternalName = old.GridExternalName; + ServiceToken = old.ServiceToken; + ClientIPAddress = old.ClientIPAddress; + MyIpAddress = old.MyIpAddress; + } + } } } diff --git a/OpenSim/Services/HypergridService/UserAgentServiceBase.cs b/OpenSim/Services/HypergridService/UserAgentServiceBase.cs new file mode 100644 index 0000000000..a00e5a6a08 --- /dev/null +++ b/OpenSim/Services/HypergridService/UserAgentServiceBase.cs @@ -0,0 +1,84 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Reflection; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Data; +using OpenSim.Services.Interfaces; +using OpenSim.Services.Base; + +namespace OpenSim.Services.HypergridService +{ + public class UserAgentServiceBase : ServiceBase + { + protected IHGTravelingData m_Database = null; + + public UserAgentServiceBase(IConfigSource config) + : base(config) + { + string dllName = String.Empty; + string connString = String.Empty; + string realm = "hg_traveling_data"; + + // + // Try reading the [DatabaseService] section, if it exists + // + IConfig dbConfig = config.Configs["DatabaseService"]; + if (dbConfig != null) + { + if (dllName == String.Empty) + dllName = dbConfig.GetString("StorageProvider", String.Empty); + if (connString == String.Empty) + connString = dbConfig.GetString("ConnectionString", String.Empty); + } + + // + // [UserAgentService] section overrides [DatabaseService], if it exists + // + IConfig gridConfig = config.Configs["UserAgentService"]; + if (gridConfig != null) + { + dllName = gridConfig.GetString("StorageProvider", dllName); + connString = gridConfig.GetString("ConnectionString", connString); + realm = gridConfig.GetString("Realm", realm); + } + + // + // We tried, but this doesn't exist. We can't proceed. + // + if (dllName.Equals(String.Empty)) + throw new Exception("No StorageProvider configured"); + + m_Database = LoadPlugin(dllName, new Object[] { connString, realm }); + if (m_Database == null) + throw new Exception("Could not find a storage interface in the given module"); + + } + } +} diff --git a/OpenSim/Services/Interfaces/ISimulationService.cs b/OpenSim/Services/Interfaces/ISimulationService.cs index b10a85c24e..1c82b3e56c 100644 --- a/OpenSim/Services/Interfaces/ISimulationService.cs +++ b/OpenSim/Services/Interfaces/ISimulationService.cs @@ -75,8 +75,6 @@ namespace OpenSim.Services.Interfaces /// bool UpdateAgent(GridRegion destination, AgentPosition data); - bool RetrieveAgent(GridRegion destination, UUID id, out IAgentData agent); - bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason); /// @@ -95,7 +93,7 @@ namespace OpenSim.Services.Interfaces /// /// /// - bool CloseAgent(GridRegion destination, UUID id); + bool CloseAgent(GridRegion destination, UUID id, string auth_token); #endregion Agents diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index c660501dbe..2fc3f0b3c8 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -584,7 +584,7 @@ namespace OpenSim.Tests.Common.Mock { AgentCircuitData agentData = new AgentCircuitData(); agentData.AgentID = AgentId; - agentData.SessionID = UUID.Zero; + agentData.SessionID = SessionId; agentData.SecureSessionID = UUID.Zero; agentData.circuitcode = m_circuitCode; agentData.child = false; diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 1c53935dff..4ddefba5f3 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -955,6 +955,10 @@ ;; Enables the groups module ; Enabled = false + ;# {LevelGroupCreate} {Enabled:true} {User level for creating groups} {} 0 + ;; Minimum user level required to create groups + ;LevelGroupCreate = 0 + ;# {Module} {Enabled:true} {Groups module to use? (Use GroupsModule to use Flotsam/Simian)} {Default "Groups Module V2"} Default ;; The default module can use a PHP XmlRpc server from the Flotsam project at ;; http://code.google.com/p/flotsam/