From 518a8b9f2ac09a5060e2e59c913dfbe7faf397ef Mon Sep 17 00:00:00 2001 From: Jeff Ames Date: Tue, 25 Nov 2008 16:00:55 +0000 Subject: Update svn properties. --- .../Hypergrid/HGGridServicesStandalone.cs | 1856 ++++++++++---------- 1 file changed, 928 insertions(+), 928 deletions(-) (limited to 'OpenSim/Region/Communications/Hypergrid/HGGridServicesStandalone.cs') diff --git a/OpenSim/Region/Communications/Hypergrid/HGGridServicesStandalone.cs b/OpenSim/Region/Communications/Hypergrid/HGGridServicesStandalone.cs index 4dc26e0..5fb9615 100644 --- a/OpenSim/Region/Communications/Hypergrid/HGGridServicesStandalone.cs +++ b/OpenSim/Region/Communications/Hypergrid/HGGridServicesStandalone.cs @@ -1,928 +1,928 @@ -/** - * Copyright (c) 2008, Contributors. All rights reserved. - * 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 Organizations nor the names of Individual - * Contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR 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; -using System.Collections.Generic; -using System.Net; -using System.Net.Sockets; -using System.Reflection; -using System.Runtime.Remoting; -using System.Runtime.Remoting.Channels; -using System.Runtime.Remoting.Channels.Tcp; -using System.Security.Authentication; - -using OpenSim.Framework; -using OpenSim.Framework.Communications; -using OpenSim.Framework.Communications.Cache; -using OpenSim.Framework.Servers; -using OpenSim.Region.Communications.Local; -using OpenSim.Region.Communications.OGS1; -using OpenSim.Region.Environment.Scenes; - -using OpenMetaverse; -using Nwc.XmlRpc; -using log4net; - -namespace OpenSim.Region.Communications.Hypergrid -{ - public class HGGridServicesStandalone : HGGridServices - { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - /// - /// Encapsulate local backend services for manipulation of local regions - /// - protected LocalBackEndServices m_localBackend = new LocalBackEndServices(); - - private Dictionary m_deadRegionCache = new Dictionary(); - - public LocalBackEndServices LocalBackend - { - get { return m_localBackend; } - } - - public override string gdebugRegionName - { - get { return m_localBackend.gdebugRegionName; } - set { m_localBackend.gdebugRegionName = value; } - } - - public override bool RegionLoginsEnabled - { - get { return m_localBackend.RegionLoginsEnabled; } - set { m_localBackend.RegionLoginsEnabled = value; } - } - - - public HGGridServicesStandalone(NetworkServersInfo servers_info, BaseHttpServer httpServe, AssetCache asscache, SceneManager sman) - : base(servers_info, httpServe, asscache, sman) - { - //Respond to Grid Services requests - httpServer.AddXmlRPCHandler("logoff_user", LogOffUser); - httpServer.AddXmlRPCHandler("check", PingCheckReply); - httpServer.AddXmlRPCHandler("land_data", LandData); - - StartRemoting(); - } - - #region IGridServices interface - - public override RegionCommsListener RegisterRegion(RegionInfo regionInfo) - { - if (!regionInfo.RegionID.Equals(UUID.Zero)) - { - m_regionsOnInstance.Add(regionInfo); - return m_localBackend.RegisterRegion(regionInfo); - } - else - return base.RegisterRegion(regionInfo); - - } - - public override bool DeregisterRegion(RegionInfo regionInfo) - { - bool success = m_localBackend.DeregisterRegion(regionInfo); - if (!success) - success = base.DeregisterRegion(regionInfo); - return success; - } - - public override List RequestNeighbours(uint x, uint y) - { - List neighbours = m_localBackend.RequestNeighbours(x, y); - List remotes = base.RequestNeighbours(x, y); - neighbours.AddRange(remotes); - - return neighbours; - } - - public override RegionInfo RequestNeighbourInfo(UUID Region_UUID) - { - RegionInfo info = m_localBackend.RequestNeighbourInfo(Region_UUID); - if (info == null) - info = base.RequestNeighbourInfo(Region_UUID); - return info; - } - - public override RegionInfo RequestNeighbourInfo(ulong regionHandle) - { - RegionInfo info = m_localBackend.RequestNeighbourInfo(regionHandle); - //m_log.Info("[HGrid] Request neighbor info, local backend returned " + info); - if (info == null) - info = base.RequestNeighbourInfo(regionHandle); - return info; - } - - public override RegionInfo RequestClosestRegion(string regionName) - { - RegionInfo info = m_localBackend.RequestClosestRegion(regionName); - if (info == null) - info = base.RequestClosestRegion(regionName); - return info; - } - - public override List RequestNeighbourMapBlocks(int minX, int minY, int maxX, int maxY) - { - //m_log.Info("[HGrid] Request map blocks " + minX + "-" + minY + "-" + maxX + "-" + maxY); - List neighbours = m_localBackend.RequestNeighbourMapBlocks(minX, minY, maxX, maxY); - List remotes = base.RequestNeighbourMapBlocks(minX, minY, maxX, maxY); - neighbours.AddRange(remotes); - - return neighbours; - } - - public override LandData RequestLandData(ulong regionHandle, uint x, uint y) - { - LandData land = m_localBackend.RequestLandData(regionHandle, x, y); - if (land == null) - land = base.RequestLandData(regionHandle, x, y); - return land; - } - - public override List RequestNamedRegions(string name, int maxNumber) - { - List infos = m_localBackend.RequestNamedRegions(name, maxNumber); - List remotes = base.RequestNamedRegions(name, maxNumber); - infos.AddRange(remotes); - return infos; - } - - #endregion - - #region XML Request Handlers - - /// - /// A ping / version check - /// - /// - /// - public virtual XmlRpcResponse PingCheckReply(XmlRpcRequest request) - { - XmlRpcResponse response = new XmlRpcResponse(); - - Hashtable respData = new Hashtable(); - respData["online"] = "true"; - - m_localBackend.PingCheckReply(respData); - - response.Value = respData; - - return response; - } - - - // Grid Request Processing - /// - /// Ooops, our Agent must be dead if we're getting this request! - /// - /// - /// - public XmlRpcResponse LogOffUser(XmlRpcRequest request) - { - m_log.Debug("[HGrid]: LogOff User Called"); - - Hashtable requestData = (Hashtable)request.Params[0]; - string message = (string)requestData["message"]; - UUID agentID = UUID.Zero; - UUID RegionSecret = UUID.Zero; - UUID.TryParse((string)requestData["agent_id"], out agentID); - UUID.TryParse((string)requestData["region_secret"], out RegionSecret); - - ulong regionHandle = Convert.ToUInt64((string)requestData["regionhandle"]); - - m_localBackend.TriggerLogOffUser(regionHandle, agentID, RegionSecret, message); - - return new XmlRpcResponse(); - } - - /// - /// Someone asked us about parcel-information - /// - /// - /// - public XmlRpcResponse LandData(XmlRpcRequest request) - { - Hashtable requestData = (Hashtable)request.Params[0]; - ulong regionHandle = Convert.ToUInt64(requestData["region_handle"]); - uint x = Convert.ToUInt32(requestData["x"]); - uint y = Convert.ToUInt32(requestData["y"]); - m_log.DebugFormat("[HGrid]: Got XML reqeuest for land data at {0}, {1} in region {2}", x, y, regionHandle); - - LandData landData = m_localBackend.RequestLandData(regionHandle, x, y); - Hashtable hash = new Hashtable(); - if (landData != null) - { - // for now, only push out the data we need for answering a ParcelInfoReqeust - hash["AABBMax"] = landData.AABBMax.ToString(); - hash["AABBMin"] = landData.AABBMin.ToString(); - hash["Area"] = landData.Area.ToString(); - hash["AuctionID"] = landData.AuctionID.ToString(); - hash["Description"] = landData.Description; - hash["Flags"] = landData.Flags.ToString(); - hash["GlobalID"] = landData.GlobalID.ToString(); - hash["Name"] = landData.Name; - hash["OwnerID"] = landData.OwnerID.ToString(); - hash["SalePrice"] = landData.SalePrice.ToString(); - hash["SnapshotID"] = landData.SnapshotID.ToString(); - hash["UserLocation"] = landData.UserLocation.ToString(); - } - - XmlRpcResponse response = new XmlRpcResponse(); - response.Value = hash; - return response; - } - - #endregion - - #region Remoting - - /// - /// Start listening for .net remoting calls from other regions. - /// - private void StartRemoting() - { - m_log.Info("[HGrid]: Start remoting..."); - TcpChannel ch; - try - { - ch = new TcpChannel((int)NetworkServersInfo.RemotingListenerPort); - ChannelServices.RegisterChannel(ch, false); // Disabled security as Mono doesn't support this. - } - catch (Exception ex) - { - m_log.Error("[HGrid]: Exception while attempting to listen on TCP port " + (int)NetworkServersInfo.RemotingListenerPort + "."); - throw (ex); - } - - WellKnownServiceTypeEntry wellType = - new WellKnownServiceTypeEntry(typeof(OGS1InterRegionRemoting), "InterRegions", - WellKnownObjectMode.Singleton); - RemotingConfiguration.RegisterWellKnownServiceType(wellType); - InterRegionSingleton.Instance.OnArrival += TriggerExpectAvatarCrossing; - InterRegionSingleton.Instance.OnChildAgent += IncomingChildAgent; - InterRegionSingleton.Instance.OnPrimGroupArrival += IncomingPrim; - InterRegionSingleton.Instance.OnPrimGroupNear += TriggerExpectPrimCrossing; - InterRegionSingleton.Instance.OnRegionUp += TriggerRegionUp; - InterRegionSingleton.Instance.OnChildAgentUpdate += TriggerChildAgentUpdate; - InterRegionSingleton.Instance.OnTellRegionToCloseChildConnection += TriggerTellRegionToCloseChildConnection; - } - - - #endregion - - #region IInterRegionCommunications interface (Methods called by regions in this instance) - - public override bool ChildAgentUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData) - { - int failures = 0; - lock (m_deadRegionCache) - { - if (m_deadRegionCache.ContainsKey(regionHandle)) - { - failures = m_deadRegionCache[regionHandle]; - } - } - if (failures <= 3) - { - RegionInfo regInfo = null; - try - { - if (m_localBackend.ChildAgentUpdate(regionHandle, cAgentData)) - { - return true; - } - - regInfo = RequestNeighbourInfo(regionHandle); - if (regInfo != null) - { - //don't want to be creating a new link to the remote instance every time like we are here - bool retValue = false; - - - OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject( - typeof(OGS1InterRegionRemoting), - "tcp://" + regInfo.RemotingAddress + - ":" + regInfo.RemotingPort + - "/InterRegions"); - - if (remObject != null) - { - retValue = remObject.ChildAgentUpdate(regionHandle, cAgentData); - } - else - { - m_log.Warn("[HGrid]: remoting object not found"); - } - remObject = null; - - return retValue; - } - NoteDeadRegion(regionHandle); - - return false; - } - catch (RemotingException e) - { - NoteDeadRegion(regionHandle); - - m_log.WarnFormat( - "[HGrid]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}", - regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY); - m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); - - return false; - } - catch (SocketException e) - { - NoteDeadRegion(regionHandle); - - m_log.WarnFormat( - "[HGrid]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}", - regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY); - m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); - - return false; - } - catch (InvalidCredentialException e) - { - NoteDeadRegion(regionHandle); - - m_log.WarnFormat( - "[HGrid]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}", - regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY); - m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); - - return false; - } - catch (AuthenticationException e) - { - NoteDeadRegion(regionHandle); - - m_log.WarnFormat( - "[HGrid]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}", - regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY); - m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); - - return false; - } - catch (Exception e) - { - NoteDeadRegion(regionHandle); - - m_log.WarnFormat("[HGrid]: Unable to connect to adjacent region: {0} {1},{2}", - regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY); - m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); - - return false; - } - } - else - { - //m_log.Info("[INTERREGION]: Skipped Sending Child Update to a region because it failed too many times:" + regionHandle.ToString()); - return false; - } - } - - /// - /// Inform a region that a child agent will be on the way from a client. - /// - /// - /// - /// - public override bool InformRegionOfChildAgent(ulong regionHandle, AgentCircuitData agentData) - { - - if (m_localBackend.InformRegionOfChildAgent(regionHandle, agentData)) - { - return true; - } - return base.InformRegionOfChildAgent(regionHandle, agentData); - } - - // UGLY! - public override bool RegionUp(SerializableRegionInfo region, ulong regionhandle) - { - if (m_localBackend.RegionUp(region, regionhandle)) - return true; - return base.RegionUp(region, regionhandle); - } - - /// - /// - /// - /// - /// - /// - public override bool InformRegionOfPrimCrossing(ulong regionHandle, UUID primID, string objData, int XMLMethod) - { - int failures = 0; - lock (m_deadRegionCache) - { - if (m_deadRegionCache.ContainsKey(regionHandle)) - { - failures = m_deadRegionCache[regionHandle]; - } - } - if (failures <= 1) - { - RegionInfo regInfo = null; - try - { - if (m_localBackend.InformRegionOfPrimCrossing(regionHandle, primID, objData, XMLMethod)) - { - return true; - } - - regInfo = RequestNeighbourInfo(regionHandle); - if (regInfo != null) - { - //don't want to be creating a new link to the remote instance every time like we are here - bool retValue = false; - - OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject( - typeof(OGS1InterRegionRemoting), - "tcp://" + regInfo.RemotingAddress + - ":" + regInfo.RemotingPort + - "/InterRegions"); - - if (remObject != null) - { - retValue = remObject.InformRegionOfPrimCrossing(regionHandle, primID.Guid, objData, XMLMethod); - } - else - { - m_log.Warn("[HGrid]: Remoting object not found"); - } - remObject = null; - - return retValue; - } - NoteDeadRegion(regionHandle); - return false; - } - catch (RemotingException e) - { - NoteDeadRegion(regionHandle); - m_log.Warn("[HGrid]: Remoting Error: Unable to connect to adjacent region: " + regionHandle); - m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); - return false; - } - catch (SocketException e) - { - NoteDeadRegion(regionHandle); - m_log.Warn("[HGrid]: Remoting Error: Unable to connect to adjacent region: " + regionHandle); - m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); - return false; - } - catch (InvalidCredentialException e) - { - NoteDeadRegion(regionHandle); - m_log.Warn("[HGrid]: Invalid Credential Exception: Invalid Credentials : " + regionHandle); - m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); - return false; - } - catch (AuthenticationException e) - { - NoteDeadRegion(regionHandle); - m_log.Warn("[HGrid]: Authentication exception: Unable to connect to adjacent region: " + regionHandle); - m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); - return false; - } - catch (Exception e) - { - NoteDeadRegion(regionHandle); - m_log.Warn("[HGrid]: Unknown exception: Unable to connect to adjacent region: " + regionHandle); - m_log.DebugFormat("[HGrid]: {0}", e); - return false; - } - } - else - { - return false; - } - } - - /// - /// - /// - /// - /// - /// - /// - public override bool ExpectAvatarCrossing(ulong regionHandle, UUID agentID, Vector3 position, bool isFlying) - { - - RegionInfo[] regions = m_regionsOnInstance.ToArray(); - bool banned = false; - bool localregion = false; - - for (int i = 0; i < regions.Length; i++) - { - if (regions[i] != null) - { - if (regions[i].RegionHandle == regionHandle) - { - localregion = true; - if (regions[i].EstateSettings.IsBanned(agentID)) - { - banned = true; - break; - } - } - } - } - - if (banned) - return false; - if (localregion) - return m_localBackend.ExpectAvatarCrossing(regionHandle, agentID, position, isFlying); - - return base.ExpectAvatarCrossing(regionHandle, agentID, position, isFlying); - - } - - public override bool ExpectPrimCrossing(ulong regionHandle, UUID agentID, Vector3 position, bool isPhysical) - { - RegionInfo regInfo = null; - try - { - if (m_localBackend.TriggerExpectPrimCrossing(regionHandle, agentID, position, isPhysical)) - { - return true; - } - - regInfo = RequestNeighbourInfo(regionHandle); - if (regInfo != null) - { - bool retValue = false; - OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject( - typeof(OGS1InterRegionRemoting), - "tcp://" + regInfo.RemotingAddress + - ":" + regInfo.RemotingPort + - "/InterRegions"); - - if (remObject != null) - { - retValue = - remObject.ExpectAvatarCrossing(regionHandle, agentID.Guid, new sLLVector3(position), - isPhysical); - } - else - { - m_log.Warn("[HGrid]: Remoting object not found"); - } - remObject = null; - - return retValue; - } - //TODO need to see if we know about where this region is and use .net remoting - // to inform it. - NoteDeadRegion(regionHandle); - return false; - } - catch (RemotingException e) - { - NoteDeadRegion(regionHandle); - m_log.Warn("[HGrid]: Remoting Error: Unable to connect to adjacent region: " + regionHandle); - m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); - return false; - } - catch (SocketException e) - { - NoteDeadRegion(regionHandle); - m_log.Warn("[HGrid]: Remoting Error: Unable to connect to adjacent region: " + regionHandle); - m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); - return false; - } - catch (InvalidCredentialException e) - { - NoteDeadRegion(regionHandle); - m_log.Warn("[HGrid]: Invalid Credential Exception: Invalid Credentials : " + regionHandle); - m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); - return false; - } - catch (AuthenticationException e) - { - NoteDeadRegion(regionHandle); - m_log.Warn("[HGrid]: Authentication exception: Unable to connect to adjacent region: " + regionHandle); - m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); - return false; - } - catch (Exception e) - { - NoteDeadRegion(regionHandle); - m_log.Warn("[HGrid]: Unknown exception: Unable to connect to adjacent region: " + regionHandle); - m_log.DebugFormat("[HGrid]: {0}", e); - return false; - } - } - - public override bool TellRegionToCloseChildConnection(ulong regionHandle, UUID agentID) - { - RegionInfo regInfo = null; - try - { - if (m_localBackend.TriggerTellRegionToCloseChildConnection(regionHandle, agentID)) - { - return true; - } - - regInfo = RequestNeighbourInfo(regionHandle); - if (regInfo != null) - { - // bool retValue = false; - OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject( - typeof(OGS1InterRegionRemoting), - "tcp://" + regInfo.RemotingAddress + - ":" + regInfo.RemotingPort + - "/InterRegions"); - - if (remObject != null) - { - // retValue = - remObject.TellRegionToCloseChildConnection(regionHandle, agentID.Guid); - } - else - { - m_log.Warn("[HGrid]: Remoting object not found"); - } - remObject = null; - - return true; - } - //TODO need to see if we know about where this region is and use .net remoting - // to inform it. - NoteDeadRegion(regionHandle); - return false; - } - catch (RemotingException) - { - NoteDeadRegion(regionHandle); - m_log.Warn("[HGrid]: Remoting Error: Unable to connect to adjacent region to tell it to close child agents: " + regInfo.RegionName + - " " + regInfo.RegionLocX + "," + regInfo.RegionLocY); - //m_log.Debug(e.ToString()); - return false; - } - catch (SocketException e) - { - NoteDeadRegion(regionHandle); - m_log.Warn("[HGridS]: Socket Error: Unable to connect to adjacent region using tcp://" + - regInfo.RemotingAddress + - ":" + regInfo.RemotingPort + - "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY + - " - Is this neighbor up?"); - m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); - return false; - } - catch (InvalidCredentialException e) - { - NoteDeadRegion(regionHandle); - m_log.Warn("[HGrid]: Invalid Credentials: Unable to connect to adjacent region using tcp://" + - regInfo.RemotingAddress + - ":" + regInfo.RemotingPort + - "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY); - m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); - return false; - } - catch (AuthenticationException e) - { - NoteDeadRegion(regionHandle); - m_log.Warn("[HGrid]: Authentication exception: Unable to connect to adjacent region using tcp://" + - regInfo.RemotingAddress + - ":" + regInfo.RemotingPort + - "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY); - m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); - return false; - } - catch (WebException e) - { - NoteDeadRegion(regionHandle); - m_log.Warn("[HGrid]: WebException exception: Unable to connect to adjacent region using tcp://" + - regInfo.RemotingAddress + - ":" + regInfo.RemotingPort + - "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY); - m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); - return false; - } - catch (Exception e) - { - NoteDeadRegion(regionHandle); - // This line errors with a Null Reference Exception.. Why? @.@ - //m_log.Warn("Unknown exception: Unable to connect to adjacent region using tcp://" + regInfo.RemotingAddress + - // ":" + regInfo.RemotingPort + - //"/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY + " - This is likely caused by an incompatibility in the protocol between this sim and that one"); - m_log.DebugFormat("[HGrid]: {0}", e); - return false; - } - } - - public override bool AcknowledgeAgentCrossed(ulong regionHandle, UUID agentId) - { - return m_localBackend.AcknowledgeAgentCrossed(regionHandle, agentId); - } - - public override bool AcknowledgePrimCrossed(ulong regionHandle, UUID primId) - { - return m_localBackend.AcknowledgePrimCrossed(regionHandle, primId); - } - - #endregion - - #region Methods triggered by calls from external instances - - /// - /// - /// - /// - /// - /// - public bool IncomingChildAgent(ulong regionHandle, AgentCircuitData agentData) - { - HGIncomingChildAgent(regionHandle, agentData); - - m_log.Info("[HGrid]: " + gdebugRegionName + ": Incoming HGrid Agent " + agentData.firstname + " " + agentData.lastname); - - return m_localBackend.IncomingChildAgent(regionHandle, agentData); - } - - public bool TriggerRegionUp(RegionUpData regionData, ulong regionhandle) - { - m_log.Info( - "[HGrid]: " + - m_localBackend._gdebugRegionName + "Incoming HGrid RegionUpReport: " + "(" + regionData.X + - "," + regionData.Y + "). Giving this region a fresh set of 'dead' tries"); - - RegionInfo nRegionInfo = new RegionInfo(); - nRegionInfo.SetEndPoint("127.0.0.1", regionData.PORT); - nRegionInfo.ExternalHostName = regionData.IPADDR; - nRegionInfo.RegionLocX = regionData.X; - nRegionInfo.RegionLocY = regionData.Y; - - lock (m_deadRegionCache) - { - if (m_deadRegionCache.ContainsKey(nRegionInfo.RegionHandle)) - { - m_deadRegionCache.Remove(nRegionInfo.RegionHandle); - } - } - - return m_localBackend.TriggerRegionUp(nRegionInfo, regionhandle); - } - - public bool TriggerChildAgentUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData) - { - //m_log.Info("[INTER]: Incoming HGrid Child Agent Data Update"); - - return m_localBackend.TriggerChildAgentUpdate(regionHandle, cAgentData); - } - - /// - /// - /// - /// - /// - /// - public bool IncomingPrim(ulong regionHandle, UUID primID, string objData, int XMLMethod) - { - m_localBackend.TriggerExpectPrim(regionHandle, primID, objData, XMLMethod); - - return true; - } - - /// - /// - /// - /// - /// - /// - /// - public bool TriggerExpectAvatarCrossing(ulong regionHandle, UUID agentID, Vector3 position, bool isFlying) - { - return m_localBackend.TriggerExpectAvatarCrossing(regionHandle, agentID, position, isFlying); - } - - public bool TriggerExpectPrimCrossing(ulong regionHandle, UUID agentID, Vector3 position, bool isPhysical) - { - return m_localBackend.TriggerExpectPrimCrossing(regionHandle, agentID, position, isPhysical); - } - - public bool TriggerTellRegionToCloseChildConnection(ulong regionHandle, UUID agentID) - { - return m_localBackend.TriggerTellRegionToCloseChildConnection(regionHandle, agentID); - } - - int timeOut = 10; //10 seconds - /// - /// Check that a region is available for TCP comms. This is necessary for .NET remoting between regions. - /// - /// - /// - /// - /// - public bool CheckRegion(string address, uint port, bool retry) - { - bool available = false; - bool timed_out = true; - - IPAddress ia; - IPAddress.TryParse(address, out ia); - IPEndPoint m_EndPoint = new IPEndPoint(ia, (int)port); - - AsyncCallback callback = delegate(IAsyncResult iar) - { - Socket s = (Socket)iar.AsyncState; - try - { - s.EndConnect(iar); - available = true; - timed_out = false; - } - catch (Exception e) - { - m_log.DebugFormat( - "[HGrid]: Callback EndConnect exception: {0}:{1}", e.Message, e.StackTrace); - } - - s.Close(); - }; - - try - { - Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - IAsyncResult ar = socket.BeginConnect(m_EndPoint, callback, socket); - ar.AsyncWaitHandle.WaitOne(timeOut * 1000, false); - } - catch (Exception e) - { - m_log.DebugFormat( - "[HGrid]: CheckRegion Socket Setup exception: {0}:{1}", e.Message, e.StackTrace); - - return false; - } - - if (timed_out) - { - m_log.DebugFormat( - "[HGrid]: socket [{0}] timed out ({1}) waiting to obtain a connection.", - m_EndPoint, timeOut * 1000); - - if (retry) - { - return CheckRegion(address, port, false); - } - } - - return available; - } - - public override bool CheckRegion(string address, uint port) - { - return CheckRegion(address, port, true); - } - - public void NoteDeadRegion(ulong regionhandle) - { - lock (m_deadRegionCache) - { - if (m_deadRegionCache.ContainsKey(regionhandle)) - { - m_deadRegionCache[regionhandle] = m_deadRegionCache[regionhandle] + 1; - } - else - { - m_deadRegionCache.Add(regionhandle, 1); - } - } - - } - - #endregion - - - } -} +/** + * Copyright (c) 2008, Contributors. All rights reserved. + * 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 Organizations nor the names of Individual + * Contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR 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; +using System.Collections.Generic; +using System.Net; +using System.Net.Sockets; +using System.Reflection; +using System.Runtime.Remoting; +using System.Runtime.Remoting.Channels; +using System.Runtime.Remoting.Channels.Tcp; +using System.Security.Authentication; + +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Framework.Communications.Cache; +using OpenSim.Framework.Servers; +using OpenSim.Region.Communications.Local; +using OpenSim.Region.Communications.OGS1; +using OpenSim.Region.Environment.Scenes; + +using OpenMetaverse; +using Nwc.XmlRpc; +using log4net; + +namespace OpenSim.Region.Communications.Hypergrid +{ + public class HGGridServicesStandalone : HGGridServices + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + /// + /// Encapsulate local backend services for manipulation of local regions + /// + protected LocalBackEndServices m_localBackend = new LocalBackEndServices(); + + private Dictionary m_deadRegionCache = new Dictionary(); + + public LocalBackEndServices LocalBackend + { + get { return m_localBackend; } + } + + public override string gdebugRegionName + { + get { return m_localBackend.gdebugRegionName; } + set { m_localBackend.gdebugRegionName = value; } + } + + public override bool RegionLoginsEnabled + { + get { return m_localBackend.RegionLoginsEnabled; } + set { m_localBackend.RegionLoginsEnabled = value; } + } + + + public HGGridServicesStandalone(NetworkServersInfo servers_info, BaseHttpServer httpServe, AssetCache asscache, SceneManager sman) + : base(servers_info, httpServe, asscache, sman) + { + //Respond to Grid Services requests + httpServer.AddXmlRPCHandler("logoff_user", LogOffUser); + httpServer.AddXmlRPCHandler("check", PingCheckReply); + httpServer.AddXmlRPCHandler("land_data", LandData); + + StartRemoting(); + } + + #region IGridServices interface + + public override RegionCommsListener RegisterRegion(RegionInfo regionInfo) + { + if (!regionInfo.RegionID.Equals(UUID.Zero)) + { + m_regionsOnInstance.Add(regionInfo); + return m_localBackend.RegisterRegion(regionInfo); + } + else + return base.RegisterRegion(regionInfo); + + } + + public override bool DeregisterRegion(RegionInfo regionInfo) + { + bool success = m_localBackend.DeregisterRegion(regionInfo); + if (!success) + success = base.DeregisterRegion(regionInfo); + return success; + } + + public override List RequestNeighbours(uint x, uint y) + { + List neighbours = m_localBackend.RequestNeighbours(x, y); + List remotes = base.RequestNeighbours(x, y); + neighbours.AddRange(remotes); + + return neighbours; + } + + public override RegionInfo RequestNeighbourInfo(UUID Region_UUID) + { + RegionInfo info = m_localBackend.RequestNeighbourInfo(Region_UUID); + if (info == null) + info = base.RequestNeighbourInfo(Region_UUID); + return info; + } + + public override RegionInfo RequestNeighbourInfo(ulong regionHandle) + { + RegionInfo info = m_localBackend.RequestNeighbourInfo(regionHandle); + //m_log.Info("[HGrid] Request neighbor info, local backend returned " + info); + if (info == null) + info = base.RequestNeighbourInfo(regionHandle); + return info; + } + + public override RegionInfo RequestClosestRegion(string regionName) + { + RegionInfo info = m_localBackend.RequestClosestRegion(regionName); + if (info == null) + info = base.RequestClosestRegion(regionName); + return info; + } + + public override List RequestNeighbourMapBlocks(int minX, int minY, int maxX, int maxY) + { + //m_log.Info("[HGrid] Request map blocks " + minX + "-" + minY + "-" + maxX + "-" + maxY); + List neighbours = m_localBackend.RequestNeighbourMapBlocks(minX, minY, maxX, maxY); + List remotes = base.RequestNeighbourMapBlocks(minX, minY, maxX, maxY); + neighbours.AddRange(remotes); + + return neighbours; + } + + public override LandData RequestLandData(ulong regionHandle, uint x, uint y) + { + LandData land = m_localBackend.RequestLandData(regionHandle, x, y); + if (land == null) + land = base.RequestLandData(regionHandle, x, y); + return land; + } + + public override List RequestNamedRegions(string name, int maxNumber) + { + List infos = m_localBackend.RequestNamedRegions(name, maxNumber); + List remotes = base.RequestNamedRegions(name, maxNumber); + infos.AddRange(remotes); + return infos; + } + + #endregion + + #region XML Request Handlers + + /// + /// A ping / version check + /// + /// + /// + public virtual XmlRpcResponse PingCheckReply(XmlRpcRequest request) + { + XmlRpcResponse response = new XmlRpcResponse(); + + Hashtable respData = new Hashtable(); + respData["online"] = "true"; + + m_localBackend.PingCheckReply(respData); + + response.Value = respData; + + return response; + } + + + // Grid Request Processing + /// + /// Ooops, our Agent must be dead if we're getting this request! + /// + /// + /// + public XmlRpcResponse LogOffUser(XmlRpcRequest request) + { + m_log.Debug("[HGrid]: LogOff User Called"); + + Hashtable requestData = (Hashtable)request.Params[0]; + string message = (string)requestData["message"]; + UUID agentID = UUID.Zero; + UUID RegionSecret = UUID.Zero; + UUID.TryParse((string)requestData["agent_id"], out agentID); + UUID.TryParse((string)requestData["region_secret"], out RegionSecret); + + ulong regionHandle = Convert.ToUInt64((string)requestData["regionhandle"]); + + m_localBackend.TriggerLogOffUser(regionHandle, agentID, RegionSecret, message); + + return new XmlRpcResponse(); + } + + /// + /// Someone asked us about parcel-information + /// + /// + /// + public XmlRpcResponse LandData(XmlRpcRequest request) + { + Hashtable requestData = (Hashtable)request.Params[0]; + ulong regionHandle = Convert.ToUInt64(requestData["region_handle"]); + uint x = Convert.ToUInt32(requestData["x"]); + uint y = Convert.ToUInt32(requestData["y"]); + m_log.DebugFormat("[HGrid]: Got XML reqeuest for land data at {0}, {1} in region {2}", x, y, regionHandle); + + LandData landData = m_localBackend.RequestLandData(regionHandle, x, y); + Hashtable hash = new Hashtable(); + if (landData != null) + { + // for now, only push out the data we need for answering a ParcelInfoReqeust + hash["AABBMax"] = landData.AABBMax.ToString(); + hash["AABBMin"] = landData.AABBMin.ToString(); + hash["Area"] = landData.Area.ToString(); + hash["AuctionID"] = landData.AuctionID.ToString(); + hash["Description"] = landData.Description; + hash["Flags"] = landData.Flags.ToString(); + hash["GlobalID"] = landData.GlobalID.ToString(); + hash["Name"] = landData.Name; + hash["OwnerID"] = landData.OwnerID.ToString(); + hash["SalePrice"] = landData.SalePrice.ToString(); + hash["SnapshotID"] = landData.SnapshotID.ToString(); + hash["UserLocation"] = landData.UserLocation.ToString(); + } + + XmlRpcResponse response = new XmlRpcResponse(); + response.Value = hash; + return response; + } + + #endregion + + #region Remoting + + /// + /// Start listening for .net remoting calls from other regions. + /// + private void StartRemoting() + { + m_log.Info("[HGrid]: Start remoting..."); + TcpChannel ch; + try + { + ch = new TcpChannel((int)NetworkServersInfo.RemotingListenerPort); + ChannelServices.RegisterChannel(ch, false); // Disabled security as Mono doesn't support this. + } + catch (Exception ex) + { + m_log.Error("[HGrid]: Exception while attempting to listen on TCP port " + (int)NetworkServersInfo.RemotingListenerPort + "."); + throw (ex); + } + + WellKnownServiceTypeEntry wellType = + new WellKnownServiceTypeEntry(typeof(OGS1InterRegionRemoting), "InterRegions", + WellKnownObjectMode.Singleton); + RemotingConfiguration.RegisterWellKnownServiceType(wellType); + InterRegionSingleton.Instance.OnArrival += TriggerExpectAvatarCrossing; + InterRegionSingleton.Instance.OnChildAgent += IncomingChildAgent; + InterRegionSingleton.Instance.OnPrimGroupArrival += IncomingPrim; + InterRegionSingleton.Instance.OnPrimGroupNear += TriggerExpectPrimCrossing; + InterRegionSingleton.Instance.OnRegionUp += TriggerRegionUp; + InterRegionSingleton.Instance.OnChildAgentUpdate += TriggerChildAgentUpdate; + InterRegionSingleton.Instance.OnTellRegionToCloseChildConnection += TriggerTellRegionToCloseChildConnection; + } + + + #endregion + + #region IInterRegionCommunications interface (Methods called by regions in this instance) + + public override bool ChildAgentUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData) + { + int failures = 0; + lock (m_deadRegionCache) + { + if (m_deadRegionCache.ContainsKey(regionHandle)) + { + failures = m_deadRegionCache[regionHandle]; + } + } + if (failures <= 3) + { + RegionInfo regInfo = null; + try + { + if (m_localBackend.ChildAgentUpdate(regionHandle, cAgentData)) + { + return true; + } + + regInfo = RequestNeighbourInfo(regionHandle); + if (regInfo != null) + { + //don't want to be creating a new link to the remote instance every time like we are here + bool retValue = false; + + + OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject( + typeof(OGS1InterRegionRemoting), + "tcp://" + regInfo.RemotingAddress + + ":" + regInfo.RemotingPort + + "/InterRegions"); + + if (remObject != null) + { + retValue = remObject.ChildAgentUpdate(regionHandle, cAgentData); + } + else + { + m_log.Warn("[HGrid]: remoting object not found"); + } + remObject = null; + + return retValue; + } + NoteDeadRegion(regionHandle); + + return false; + } + catch (RemotingException e) + { + NoteDeadRegion(regionHandle); + + m_log.WarnFormat( + "[HGrid]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}", + regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY); + m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); + + return false; + } + catch (SocketException e) + { + NoteDeadRegion(regionHandle); + + m_log.WarnFormat( + "[HGrid]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}", + regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY); + m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); + + return false; + } + catch (InvalidCredentialException e) + { + NoteDeadRegion(regionHandle); + + m_log.WarnFormat( + "[HGrid]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}", + regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY); + m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); + + return false; + } + catch (AuthenticationException e) + { + NoteDeadRegion(regionHandle); + + m_log.WarnFormat( + "[HGrid]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}", + regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY); + m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); + + return false; + } + catch (Exception e) + { + NoteDeadRegion(regionHandle); + + m_log.WarnFormat("[HGrid]: Unable to connect to adjacent region: {0} {1},{2}", + regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY); + m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); + + return false; + } + } + else + { + //m_log.Info("[INTERREGION]: Skipped Sending Child Update to a region because it failed too many times:" + regionHandle.ToString()); + return false; + } + } + + /// + /// Inform a region that a child agent will be on the way from a client. + /// + /// + /// + /// + public override bool InformRegionOfChildAgent(ulong regionHandle, AgentCircuitData agentData) + { + + if (m_localBackend.InformRegionOfChildAgent(regionHandle, agentData)) + { + return true; + } + return base.InformRegionOfChildAgent(regionHandle, agentData); + } + + // UGLY! + public override bool RegionUp(SerializableRegionInfo region, ulong regionhandle) + { + if (m_localBackend.RegionUp(region, regionhandle)) + return true; + return base.RegionUp(region, regionhandle); + } + + /// + /// + /// + /// + /// + /// + public override bool InformRegionOfPrimCrossing(ulong regionHandle, UUID primID, string objData, int XMLMethod) + { + int failures = 0; + lock (m_deadRegionCache) + { + if (m_deadRegionCache.ContainsKey(regionHandle)) + { + failures = m_deadRegionCache[regionHandle]; + } + } + if (failures <= 1) + { + RegionInfo regInfo = null; + try + { + if (m_localBackend.InformRegionOfPrimCrossing(regionHandle, primID, objData, XMLMethod)) + { + return true; + } + + regInfo = RequestNeighbourInfo(regionHandle); + if (regInfo != null) + { + //don't want to be creating a new link to the remote instance every time like we are here + bool retValue = false; + + OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject( + typeof(OGS1InterRegionRemoting), + "tcp://" + regInfo.RemotingAddress + + ":" + regInfo.RemotingPort + + "/InterRegions"); + + if (remObject != null) + { + retValue = remObject.InformRegionOfPrimCrossing(regionHandle, primID.Guid, objData, XMLMethod); + } + else + { + m_log.Warn("[HGrid]: Remoting object not found"); + } + remObject = null; + + return retValue; + } + NoteDeadRegion(regionHandle); + return false; + } + catch (RemotingException e) + { + NoteDeadRegion(regionHandle); + m_log.Warn("[HGrid]: Remoting Error: Unable to connect to adjacent region: " + regionHandle); + m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); + return false; + } + catch (SocketException e) + { + NoteDeadRegion(regionHandle); + m_log.Warn("[HGrid]: Remoting Error: Unable to connect to adjacent region: " + regionHandle); + m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); + return false; + } + catch (InvalidCredentialException e) + { + NoteDeadRegion(regionHandle); + m_log.Warn("[HGrid]: Invalid Credential Exception: Invalid Credentials : " + regionHandle); + m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); + return false; + } + catch (AuthenticationException e) + { + NoteDeadRegion(regionHandle); + m_log.Warn("[HGrid]: Authentication exception: Unable to connect to adjacent region: " + regionHandle); + m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); + return false; + } + catch (Exception e) + { + NoteDeadRegion(regionHandle); + m_log.Warn("[HGrid]: Unknown exception: Unable to connect to adjacent region: " + regionHandle); + m_log.DebugFormat("[HGrid]: {0}", e); + return false; + } + } + else + { + return false; + } + } + + /// + /// + /// + /// + /// + /// + /// + public override bool ExpectAvatarCrossing(ulong regionHandle, UUID agentID, Vector3 position, bool isFlying) + { + + RegionInfo[] regions = m_regionsOnInstance.ToArray(); + bool banned = false; + bool localregion = false; + + for (int i = 0; i < regions.Length; i++) + { + if (regions[i] != null) + { + if (regions[i].RegionHandle == regionHandle) + { + localregion = true; + if (regions[i].EstateSettings.IsBanned(agentID)) + { + banned = true; + break; + } + } + } + } + + if (banned) + return false; + if (localregion) + return m_localBackend.ExpectAvatarCrossing(regionHandle, agentID, position, isFlying); + + return base.ExpectAvatarCrossing(regionHandle, agentID, position, isFlying); + + } + + public override bool ExpectPrimCrossing(ulong regionHandle, UUID agentID, Vector3 position, bool isPhysical) + { + RegionInfo regInfo = null; + try + { + if (m_localBackend.TriggerExpectPrimCrossing(regionHandle, agentID, position, isPhysical)) + { + return true; + } + + regInfo = RequestNeighbourInfo(regionHandle); + if (regInfo != null) + { + bool retValue = false; + OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject( + typeof(OGS1InterRegionRemoting), + "tcp://" + regInfo.RemotingAddress + + ":" + regInfo.RemotingPort + + "/InterRegions"); + + if (remObject != null) + { + retValue = + remObject.ExpectAvatarCrossing(regionHandle, agentID.Guid, new sLLVector3(position), + isPhysical); + } + else + { + m_log.Warn("[HGrid]: Remoting object not found"); + } + remObject = null; + + return retValue; + } + //TODO need to see if we know about where this region is and use .net remoting + // to inform it. + NoteDeadRegion(regionHandle); + return false; + } + catch (RemotingException e) + { + NoteDeadRegion(regionHandle); + m_log.Warn("[HGrid]: Remoting Error: Unable to connect to adjacent region: " + regionHandle); + m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); + return false; + } + catch (SocketException e) + { + NoteDeadRegion(regionHandle); + m_log.Warn("[HGrid]: Remoting Error: Unable to connect to adjacent region: " + regionHandle); + m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); + return false; + } + catch (InvalidCredentialException e) + { + NoteDeadRegion(regionHandle); + m_log.Warn("[HGrid]: Invalid Credential Exception: Invalid Credentials : " + regionHandle); + m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); + return false; + } + catch (AuthenticationException e) + { + NoteDeadRegion(regionHandle); + m_log.Warn("[HGrid]: Authentication exception: Unable to connect to adjacent region: " + regionHandle); + m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); + return false; + } + catch (Exception e) + { + NoteDeadRegion(regionHandle); + m_log.Warn("[HGrid]: Unknown exception: Unable to connect to adjacent region: " + regionHandle); + m_log.DebugFormat("[HGrid]: {0}", e); + return false; + } + } + + public override bool TellRegionToCloseChildConnection(ulong regionHandle, UUID agentID) + { + RegionInfo regInfo = null; + try + { + if (m_localBackend.TriggerTellRegionToCloseChildConnection(regionHandle, agentID)) + { + return true; + } + + regInfo = RequestNeighbourInfo(regionHandle); + if (regInfo != null) + { + // bool retValue = false; + OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject( + typeof(OGS1InterRegionRemoting), + "tcp://" + regInfo.RemotingAddress + + ":" + regInfo.RemotingPort + + "/InterRegions"); + + if (remObject != null) + { + // retValue = + remObject.TellRegionToCloseChildConnection(regionHandle, agentID.Guid); + } + else + { + m_log.Warn("[HGrid]: Remoting object not found"); + } + remObject = null; + + return true; + } + //TODO need to see if we know about where this region is and use .net remoting + // to inform it. + NoteDeadRegion(regionHandle); + return false; + } + catch (RemotingException) + { + NoteDeadRegion(regionHandle); + m_log.Warn("[HGrid]: Remoting Error: Unable to connect to adjacent region to tell it to close child agents: " + regInfo.RegionName + + " " + regInfo.RegionLocX + "," + regInfo.RegionLocY); + //m_log.Debug(e.ToString()); + return false; + } + catch (SocketException e) + { + NoteDeadRegion(regionHandle); + m_log.Warn("[HGridS]: Socket Error: Unable to connect to adjacent region using tcp://" + + regInfo.RemotingAddress + + ":" + regInfo.RemotingPort + + "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY + + " - Is this neighbor up?"); + m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); + return false; + } + catch (InvalidCredentialException e) + { + NoteDeadRegion(regionHandle); + m_log.Warn("[HGrid]: Invalid Credentials: Unable to connect to adjacent region using tcp://" + + regInfo.RemotingAddress + + ":" + regInfo.RemotingPort + + "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY); + m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); + return false; + } + catch (AuthenticationException e) + { + NoteDeadRegion(regionHandle); + m_log.Warn("[HGrid]: Authentication exception: Unable to connect to adjacent region using tcp://" + + regInfo.RemotingAddress + + ":" + regInfo.RemotingPort + + "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY); + m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); + return false; + } + catch (WebException e) + { + NoteDeadRegion(regionHandle); + m_log.Warn("[HGrid]: WebException exception: Unable to connect to adjacent region using tcp://" + + regInfo.RemotingAddress + + ":" + regInfo.RemotingPort + + "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY); + m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message); + return false; + } + catch (Exception e) + { + NoteDeadRegion(regionHandle); + // This line errors with a Null Reference Exception.. Why? @.@ + //m_log.Warn("Unknown exception: Unable to connect to adjacent region using tcp://" + regInfo.RemotingAddress + + // ":" + regInfo.RemotingPort + + //"/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY + " - This is likely caused by an incompatibility in the protocol between this sim and that one"); + m_log.DebugFormat("[HGrid]: {0}", e); + return false; + } + } + + public override bool AcknowledgeAgentCrossed(ulong regionHandle, UUID agentId) + { + return m_localBackend.AcknowledgeAgentCrossed(regionHandle, agentId); + } + + public override bool AcknowledgePrimCrossed(ulong regionHandle, UUID primId) + { + return m_localBackend.AcknowledgePrimCrossed(regionHandle, primId); + } + + #endregion + + #region Methods triggered by calls from external instances + + /// + /// + /// + /// + /// + /// + public bool IncomingChildAgent(ulong regionHandle, AgentCircuitData agentData) + { + HGIncomingChildAgent(regionHandle, agentData); + + m_log.Info("[HGrid]: " + gdebugRegionName + ": Incoming HGrid Agent " + agentData.firstname + " " + agentData.lastname); + + return m_localBackend.IncomingChildAgent(regionHandle, agentData); + } + + public bool TriggerRegionUp(RegionUpData regionData, ulong regionhandle) + { + m_log.Info( + "[HGrid]: " + + m_localBackend._gdebugRegionName + "Incoming HGrid RegionUpReport: " + "(" + regionData.X + + "," + regionData.Y + "). Giving this region a fresh set of 'dead' tries"); + + RegionInfo nRegionInfo = new RegionInfo(); + nRegionInfo.SetEndPoint("127.0.0.1", regionData.PORT); + nRegionInfo.ExternalHostName = regionData.IPADDR; + nRegionInfo.RegionLocX = regionData.X; + nRegionInfo.RegionLocY = regionData.Y; + + lock (m_deadRegionCache) + { + if (m_deadRegionCache.ContainsKey(nRegionInfo.RegionHandle)) + { + m_deadRegionCache.Remove(nRegionInfo.RegionHandle); + } + } + + return m_localBackend.TriggerRegionUp(nRegionInfo, regionhandle); + } + + public bool TriggerChildAgentUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData) + { + //m_log.Info("[INTER]: Incoming HGrid Child Agent Data Update"); + + return m_localBackend.TriggerChildAgentUpdate(regionHandle, cAgentData); + } + + /// + /// + /// + /// + /// + /// + public bool IncomingPrim(ulong regionHandle, UUID primID, string objData, int XMLMethod) + { + m_localBackend.TriggerExpectPrim(regionHandle, primID, objData, XMLMethod); + + return true; + } + + /// + /// + /// + /// + /// + /// + /// + public bool TriggerExpectAvatarCrossing(ulong regionHandle, UUID agentID, Vector3 position, bool isFlying) + { + return m_localBackend.TriggerExpectAvatarCrossing(regionHandle, agentID, position, isFlying); + } + + public bool TriggerExpectPrimCrossing(ulong regionHandle, UUID agentID, Vector3 position, bool isPhysical) + { + return m_localBackend.TriggerExpectPrimCrossing(regionHandle, agentID, position, isPhysical); + } + + public bool TriggerTellRegionToCloseChildConnection(ulong regionHandle, UUID agentID) + { + return m_localBackend.TriggerTellRegionToCloseChildConnection(regionHandle, agentID); + } + + int timeOut = 10; //10 seconds + /// + /// Check that a region is available for TCP comms. This is necessary for .NET remoting between regions. + /// + /// + /// + /// + /// + public bool CheckRegion(string address, uint port, bool retry) + { + bool available = false; + bool timed_out = true; + + IPAddress ia; + IPAddress.TryParse(address, out ia); + IPEndPoint m_EndPoint = new IPEndPoint(ia, (int)port); + + AsyncCallback callback = delegate(IAsyncResult iar) + { + Socket s = (Socket)iar.AsyncState; + try + { + s.EndConnect(iar); + available = true; + timed_out = false; + } + catch (Exception e) + { + m_log.DebugFormat( + "[HGrid]: Callback EndConnect exception: {0}:{1}", e.Message, e.StackTrace); + } + + s.Close(); + }; + + try + { + Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + IAsyncResult ar = socket.BeginConnect(m_EndPoint, callback, socket); + ar.AsyncWaitHandle.WaitOne(timeOut * 1000, false); + } + catch (Exception e) + { + m_log.DebugFormat( + "[HGrid]: CheckRegion Socket Setup exception: {0}:{1}", e.Message, e.StackTrace); + + return false; + } + + if (timed_out) + { + m_log.DebugFormat( + "[HGrid]: socket [{0}] timed out ({1}) waiting to obtain a connection.", + m_EndPoint, timeOut * 1000); + + if (retry) + { + return CheckRegion(address, port, false); + } + } + + return available; + } + + public override bool CheckRegion(string address, uint port) + { + return CheckRegion(address, port, true); + } + + public void NoteDeadRegion(ulong regionhandle) + { + lock (m_deadRegionCache) + { + if (m_deadRegionCache.ContainsKey(regionhandle)) + { + m_deadRegionCache[regionhandle] = m_deadRegionCache[regionhandle] + 1; + } + else + { + m_deadRegionCache.Add(regionhandle, 1); + } + } + + } + + #endregion + + + } +} -- cgit v1.1