Merge branch 'presence-refactor' of melanie@opensimulator.org:/var/git/opensim into presence-refactor

slimupdates
Melanie 2010-01-19 04:18:01 +00:00
commit a3f48a7ca6
19 changed files with 1128 additions and 268 deletions

View File

@ -38,6 +38,7 @@ using OpenMetaverse.Packets;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Statistics; using OpenSim.Framework.Statistics;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using OpenMetaverse; using OpenMetaverse;
using TokenBucket = OpenSim.Region.ClientStack.LindenUDP.TokenBucket; using TokenBucket = OpenSim.Region.ClientStack.LindenUDP.TokenBucket;
@ -900,6 +901,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (!m_scene.TryGetClient(agentID, out existingClient)) if (!m_scene.TryGetClient(agentID, out existingClient))
{ {
IHomeUsersSecurityService security = m_scene.RequestModuleInterface<IHomeUsersSecurityService>();
if (security != null)
{
IPEndPoint ep = security.GetEndPoint(sessionID);
if (ep != null && ep.ToString() != remoteEndPoint.ToString())
{
// uh-oh, this is fishy
m_log.WarnFormat("[LLUDPSERVER]: Agent {0} with session {1} connecting with unidentified end point. Refusing service.", agentID, sessionID);
m_log.WarnFormat("[LLUDPSERVER]: EP was {0}, now is {1}", ep.ToString(), remoteEndPoint.ToString());
return;
}
else if (ep != null)
{
// ok, you're home, welcome back
m_log.InfoFormat("LLUDPSERVER]: Agent {0} is coming back to this grid", agentID);
security.RemoveEndPoint(sessionID);
}
}
// Create the LLClientView // Create the LLClientView
LLClientView client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode); LLClientView client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
client.OnLogout += LogoutHandler; client.OnLogout += LogoutHandler;

View File

@ -134,8 +134,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (!sp.Scene.Permissions.CanTeleport(sp.UUID)) if (!sp.Scene.Permissions.CanTeleport(sp.UUID))
return; return;
bool destRegionUp = true;
IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>(); IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>();
// Reset animations; the viewer does that in teleports. // Reset animations; the viewer does that in teleports.
@ -183,7 +181,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags);
sp.Teleport(position); sp.Teleport(position);
} }
else else // Another region possibly in another simulator
{ {
uint x = 0, y = 0; uint x = 0, y = 0;
Utils.LongToUInts(regionHandle, out x, out y); Utils.LongToUInts(regionHandle, out x, out y);
@ -191,15 +189,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (reg != null) if (reg != null)
{ {
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: RequestTeleportToLocation to {0} in {1}",
position, reg.RegionName);
uint newRegionX = (uint)(reg.RegionHandle >> 40);
uint newRegionY = (((uint)(reg.RegionHandle)) >> 8);
uint oldRegionX = (uint)(sp.Scene.RegionInfo.RegionHandle >> 40);
uint oldRegionY = (((uint)(sp.Scene.RegionInfo.RegionHandle)) >> 8);
GridRegion finalDestination = GetFinalDestination(reg); GridRegion finalDestination = GetFinalDestination(reg);
if (finalDestination == null) if (finalDestination == null)
{ {
@ -207,220 +196,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
sp.ControllingClient.SendTeleportFailed("Problem at destination"); sp.ControllingClient.SendTeleportFailed("Problem at destination");
return; return;
} }
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final destination is x={0} y={1} uuid={2}", finalDestination.RegionLocX, finalDestination.RegionLocY, finalDestination.RegionID); m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final destination is x={0} y={1} uuid={2}",
ulong destinationHandle = finalDestination.RegionHandle; finalDestination.RegionLocX / Constants.RegionSize, finalDestination.RegionLocY / Constants.RegionSize, finalDestination.RegionID);
if (eq == null) //
sp.ControllingClient.SendTeleportLocationStart(); // This is it
//
// Let's do DNS resolution only once in this process, please! DoTeleport(sp, reg, finalDestination, position, lookAt, teleportFlags, eq);
// This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, //
// it's actually doing a lot of work. //
IPEndPoint endPoint = finalDestination.ExternalEndPoint; //
if (endPoint.Address == null)
{
// Couldn't resolve the name. Can't TP, because the viewer wants IP addresses.
destRegionUp = false;
}
if (destRegionUp)
{
// Fixing a bug where teleporting while sitting results in the avatar ending up removed from
// both regions
if (sp.ParentID != (uint)0)
sp.StandUp();
if (!sp.ValidateAttachments())
{
sp.ControllingClient.SendTeleportFailed("Inconsistent attachment state");
return;
}
// the avatar.Close below will clear the child region list. We need this below for (possibly)
// closing the child agents, so save it here (we need a copy as it is Clear()-ed).
//List<ulong> childRegions = new List<ulong>(avatar.GetKnownRegionList());
// Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport
// failure at this point (unlike a border crossing failure). So perhaps this can never fail
// once we reach here...
//avatar.Scene.RemoveCapsHandler(avatar.UUID);
string capsPath = String.Empty;
AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo();
agentCircuit.startpos = position;
agentCircuit.child = true;
agentCircuit.Appearance = sp.Appearance;
if (currentAgentCircuit != null)
agentCircuit.ServiceURLs = currentAgentCircuit.ServiceURLs;
if (NeedsNewAgent(oldRegionX, newRegionX, oldRegionY, newRegionY))
{
// brand new agent, let's create a new caps seed
agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath();
}
string reason = String.Empty;
// Let's create an agent there if one doesn't exist yet.
if (!CreateAgent(reg, finalDestination, agentCircuit, teleportFlags, out reason))
{
sp.ControllingClient.SendTeleportFailed(String.Format("Destination refused: {0}",
reason));
return;
}
// OK, it got this agent. Let's close some child agents
sp.CloseChildAgents(newRegionX, newRegionY);
if (NeedsNewAgent(oldRegionX, newRegionX, oldRegionY, newRegionY))
{
#region IP Translation for NAT
IClientIPEndpoint ipepClient;
if (sp.ClientView.TryGet(out ipepClient))
{
capsPath
= "http://"
+ NetworkUtil.GetHostFor(ipepClient.EndPoint, finalDestination.ExternalHostName)
+ ":"
+ finalDestination.HttpPort
+ CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
}
else
{
capsPath
= "http://"
+ finalDestination.ExternalHostName
+ ":"
+ finalDestination.HttpPort
+ CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
}
#endregion
if (eq != null)
{
#region IP Translation for NAT
// Uses ipepClient above
if (sp.ClientView.TryGet(out ipepClient))
{
endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address);
}
#endregion
eq.EnableSimulator(destinationHandle, endPoint, sp.UUID);
// ES makes the client send a UseCircuitCode message to the destination,
// which triggers a bunch of things there.
// So let's wait
Thread.Sleep(2000);
eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath);
}
else
{
sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint);
}
}
else
{
agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle);
capsPath = "http://" + finalDestination.ExternalHostName + ":" + finalDestination.HttpPort
+ "/CAPS/" + agentCircuit.CapsPath + "0000/";
}
// Expect avatar crossing is a heavy-duty function at the destination.
// That is where MakeRoot is called, which fetches appearance and inventory.
// Plus triggers OnMakeRoot, which spawns a series of asynchronous updates.
//m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId,
// position, false);
//{
// avatar.ControllingClient.SendTeleportFailed("Problem with destination.");
// // We should close that agent we just created over at destination...
// List<ulong> lst = new List<ulong>();
// lst.Add(reg.RegionHandle);
// SendCloseChildAgentAsync(avatar.UUID, lst);
// return;
//}
SetInTransit(sp.UUID);
// Let's send a full update of the agent. This is a synchronous call.
AgentData agent = new AgentData();
sp.CopyTo(agent);
agent.Position = position;
SetCallbackURL(agent, sp.Scene.RegionInfo);
UpdateAgent(reg, finalDestination, agent);
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, sp.UUID);
if (eq != null)
{
eq.TeleportFinishEvent(destinationHandle, 13, endPoint,
0, teleportFlags, capsPath, sp.UUID);
}
else
{
sp.ControllingClient.SendRegionTeleport(destinationHandle, 13, endPoint, 4,
teleportFlags, capsPath);
}
// TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which
// trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation
// that the client contacted the destination before we send the attachments and close things here.
if (!WaitForCallback(sp.UUID))
{
// Client never contacted destination. Let's restore everything back
sp.ControllingClient.SendTeleportFailed("Problems connecting to destination.");
ResetFromTransit(sp.UUID);
// Yikes! We should just have a ref to scene here.
//sp.Scene.InformClientOfNeighbours(sp);
EnableChildAgents(sp);
// Finally, kill the agent we just created at the destination.
m_aScene.SimulationService.CloseAgent(finalDestination, sp.UUID);
return;
}
KillEntity(sp.Scene, sp.LocalId);
sp.MakeChildAgent();
// CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it
CrossAttachmentsIntoNewRegion(finalDestination, sp, true);
// Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
if (NeedsClosing(oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
{
Thread.Sleep(5000);
sp.Close();
sp.Scene.IncomingCloseAgent(sp.UUID);
}
else
// now we have a child agent in this region.
sp.Reset();
// REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
if (sp.Scene.NeedSceneCacheClear(sp.UUID))
{
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed",
sp.UUID);
}
}
else
{
sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down");
}
} }
else else
{ {
@ -450,7 +235,228 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
} }
} }
protected virtual bool CreateAgent(GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason) protected void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq)
{
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Request Teleport to {0}:{1}:{2}/{3} final destination {4}",
reg.ExternalHostName, reg.HttpPort, reg.RegionName, position, finalDestination.RegionName);
uint newRegionX = (uint)(reg.RegionHandle >> 40);
uint newRegionY = (((uint)(reg.RegionHandle)) >> 8);
uint oldRegionX = (uint)(sp.Scene.RegionInfo.RegionHandle >> 40);
uint oldRegionY = (((uint)(sp.Scene.RegionInfo.RegionHandle)) >> 8);
ulong destinationHandle = finalDestination.RegionHandle;
if (eq == null)
sp.ControllingClient.SendTeleportLocationStart();
// Let's do DNS resolution only once in this process, please!
// This may be a costly operation. The reg.ExternalEndPoint field is not a passive field,
// it's actually doing a lot of work.
IPEndPoint endPoint = finalDestination.ExternalEndPoint;
if (endPoint.Address != null)
{
// Fixing a bug where teleporting while sitting results in the avatar ending up removed from
// both regions
if (sp.ParentID != (uint)0)
sp.StandUp();
if (!sp.ValidateAttachments())
{
sp.ControllingClient.SendTeleportFailed("Inconsistent attachment state");
return;
}
// the avatar.Close below will clear the child region list. We need this below for (possibly)
// closing the child agents, so save it here (we need a copy as it is Clear()-ed).
//List<ulong> childRegions = new List<ulong>(avatar.GetKnownRegionList());
// Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport
// failure at this point (unlike a border crossing failure). So perhaps this can never fail
// once we reach here...
//avatar.Scene.RemoveCapsHandler(avatar.UUID);
string capsPath = String.Empty;
AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo();
agentCircuit.startpos = position;
agentCircuit.child = true;
agentCircuit.Appearance = sp.Appearance;
if (currentAgentCircuit != null)
agentCircuit.ServiceURLs = currentAgentCircuit.ServiceURLs;
if (NeedsNewAgent(oldRegionX, newRegionX, oldRegionY, newRegionY))
{
// brand new agent, let's create a new caps seed
agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath();
}
string reason = String.Empty;
// Let's create an agent there if one doesn't exist yet.
if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason))
{
sp.ControllingClient.SendTeleportFailed(String.Format("Destination refused: {0}",
reason));
return;
}
// OK, it got this agent. Let's close some child agents
sp.CloseChildAgents(newRegionX, newRegionY);
if (NeedsNewAgent(oldRegionX, newRegionX, oldRegionY, newRegionY))
{
#region IP Translation for NAT
IClientIPEndpoint ipepClient;
if (sp.ClientView.TryGet(out ipepClient))
{
capsPath
= "http://"
+ NetworkUtil.GetHostFor(ipepClient.EndPoint, finalDestination.ExternalHostName)
+ ":"
+ finalDestination.HttpPort
+ CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
}
else
{
capsPath
= "http://"
+ finalDestination.ExternalHostName
+ ":"
+ finalDestination.HttpPort
+ CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
}
#endregion
if (eq != null)
{
#region IP Translation for NAT
// Uses ipepClient above
if (sp.ClientView.TryGet(out ipepClient))
{
endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address);
}
#endregion
eq.EnableSimulator(destinationHandle, endPoint, sp.UUID);
// ES makes the client send a UseCircuitCode message to the destination,
// which triggers a bunch of things there.
// So let's wait
Thread.Sleep(2000);
eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath);
}
else
{
sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint);
}
}
else
{
agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle);
capsPath = "http://" + finalDestination.ExternalHostName + ":" + finalDestination.HttpPort
+ "/CAPS/" + agentCircuit.CapsPath + "0000/";
}
// Expect avatar crossing is a heavy-duty function at the destination.
// That is where MakeRoot is called, which fetches appearance and inventory.
// Plus triggers OnMakeRoot, which spawns a series of asynchronous updates.
//m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId,
// position, false);
//{
// avatar.ControllingClient.SendTeleportFailed("Problem with destination.");
// // We should close that agent we just created over at destination...
// List<ulong> lst = new List<ulong>();
// lst.Add(reg.RegionHandle);
// SendCloseChildAgentAsync(avatar.UUID, lst);
// return;
//}
SetInTransit(sp.UUID);
// Let's send a full update of the agent. This is a synchronous call.
AgentData agent = new AgentData();
sp.CopyTo(agent);
agent.Position = position;
SetCallbackURL(agent, sp.Scene.RegionInfo);
UpdateAgent(reg, finalDestination, agent);
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, sp.UUID);
if (eq != null)
{
eq.TeleportFinishEvent(destinationHandle, 13, endPoint,
0, teleportFlags, capsPath, sp.UUID);
}
else
{
sp.ControllingClient.SendRegionTeleport(destinationHandle, 13, endPoint, 4,
teleportFlags, capsPath);
}
// TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which
// trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation
// that the client contacted the destination before we send the attachments and close things here.
if (!WaitForCallback(sp.UUID))
{
// Client never contacted destination. Let's restore everything back
sp.ControllingClient.SendTeleportFailed("Problems connecting to destination.");
ResetFromTransit(sp.UUID);
// Yikes! We should just have a ref to scene here.
//sp.Scene.InformClientOfNeighbours(sp);
EnableChildAgents(sp);
// Finally, kill the agent we just created at the destination.
m_aScene.SimulationService.CloseAgent(finalDestination, sp.UUID);
return;
}
KillEntity(sp.Scene, sp.LocalId);
sp.MakeChildAgent();
// CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it
CrossAttachmentsIntoNewRegion(finalDestination, sp, true);
// Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
if (NeedsClosing(oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
{
Thread.Sleep(5000);
sp.Close();
sp.Scene.IncomingCloseAgent(sp.UUID);
}
else
// now we have a child agent in this region.
sp.Reset();
// REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
if (sp.Scene.NeedSceneCacheClear(sp.UUID))
{
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed",
sp.UUID);
}
}
else
{
sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down");
}
}
protected virtual bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason)
{ {
return m_aScene.SimulationService.CreateAgent(finalDestination, agentCircuit, teleportFlags, out reason); return m_aScene.SimulationService.CreateAgent(finalDestination, agentCircuit, teleportFlags, out reason);
} }

View File

@ -34,6 +34,7 @@ using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Connectors.Hypergrid; using OpenSim.Services.Connectors.Hypergrid;
using OpenSim.Services.Interfaces; using OpenSim.Services.Interfaces;
using OpenSim.Server.Base;
using GridRegion = OpenSim.Services.Interfaces.GridRegion; using GridRegion = OpenSim.Services.Interfaces.GridRegion;
@ -59,6 +60,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
} }
private GatekeeperServiceConnector m_GatekeeperConnector; private GatekeeperServiceConnector m_GatekeeperConnector;
private IHomeUsersSecurityService m_Security;
#region ISharedRegionModule #region ISharedRegionModule
@ -77,12 +79,42 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
{ {
m_agentsInTransit = new List<UUID>(); m_agentsInTransit = new List<UUID>();
m_GatekeeperConnector = new GatekeeperServiceConnector(); m_GatekeeperConnector = new GatekeeperServiceConnector();
IConfig config = source.Configs["HGEntityTransferModule"];
if (config != null)
{
string dll = config.GetString("HomeUsersSecurityService", string.Empty);
if (dll != string.Empty)
{
Object[] args = new Object[] { source };
m_Security = ServerUtils.LoadPlugin<IHomeUsersSecurityService>(dll, args);
if (m_Security == null)
m_log.Debug("[HG ENTITY TRANSFER MODULE]: Unable to load Home Users Security service");
else
m_log.Debug("[HG ENTITY TRANSFER MODULE]: Home Users Security service loaded");
}
}
m_Enabled = true; m_Enabled = true;
m_log.InfoFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name); m_log.InfoFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name);
} }
} }
} }
public override void AddRegion(Scene scene)
{
base.AddRegion(scene);
if (m_Enabled)
scene.RegisterModuleInterface<IHomeUsersSecurityService>(m_Security);
}
public override void RemoveRegion(Scene scene)
{
base.AddRegion(scene);
if (m_Enabled)
scene.UnregisterModuleInterface<IHomeUsersSecurityService>(m_Security);
}
#endregion #endregion
@ -98,19 +130,101 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return true; return true;
} }
protected override bool CreateAgent(GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason) protected override bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason)
{ {
reason = string.Empty; reason = string.Empty;
if (reg.RegionLocX != finalDestination.RegionLocX && reg.RegionLocY != finalDestination.RegionLocY) if (reg.RegionLocX != finalDestination.RegionLocX || reg.RegionLocY != finalDestination.RegionLocY)
{ {
// this user is going to another grid // this user is going to another grid
reg.RegionName = finalDestination.RegionName; reg.RegionName = finalDestination.RegionName;
reg.RegionID = finalDestination.RegionID;
reg.RegionLocX = finalDestination.RegionLocX;
reg.RegionLocY = finalDestination.RegionLocY;
// Log their session and remote endpoint in the home users security service
IHomeUsersSecurityService security = sp.Scene.RequestModuleInterface<IHomeUsersSecurityService>();
if (security != null)
security.SetEndPoint(sp.ControllingClient.SessionId, sp.ControllingClient.RemoteEndPoint);
// Log them out of this grid
sp.Scene.PresenceService.LogoutAgent(agentCircuit.SessionID, sp.AbsolutePosition, sp.Lookat);
return m_GatekeeperConnector.CreateAgent(reg, agentCircuit, teleportFlags, out reason); return m_GatekeeperConnector.CreateAgent(reg, agentCircuit, teleportFlags, out reason);
} }
return m_aScene.SimulationService.CreateAgent(reg, agentCircuit, teleportFlags, out reason); return m_aScene.SimulationService.CreateAgent(reg, agentCircuit, teleportFlags, out reason);
} }
public override void TeleportHome(UUID id, IClientAPI client)
{
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.FirstName, client.LastName);
// Let's find out if this is a foreign user or a local user
UserAccount account = m_aScene.UserAccountService.GetUserAccount(m_aScene.RegionInfo.ScopeID, id);
if (account != null)
{
// local grid user
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: User is local");
base.TeleportHome(id, client);
return;
}
// Foreign user wants to go home
//
AgentCircuitData aCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode);
if (aCircuit == null || (aCircuit != null && !aCircuit.ServiceURLs.ContainsKey("GatewayURI")))
{
client.SendTeleportFailed("Your information has been lost");
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Unable to locate agent's gateway information");
return;
}
GridRegion homeGatekeeper = MakeRegion(aCircuit);
if (homeGatekeeper == null)
{
client.SendTeleportFailed("Your information has been lost");
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent's gateway information is malformed");
return;
}
Vector3 position = Vector3.UnitY, lookAt = Vector3.UnitY;
GridRegion finalDestination = m_GatekeeperConnector.GetHomeRegion(homeGatekeeper, aCircuit.AgentID, out position, out lookAt);
if (finalDestination == null)
{
client.SendTeleportFailed("Your home region could not be found");
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent's home region not found");
return;
}
ScenePresence sp = ((Scene)(client.Scene)).GetScenePresence(client.AgentId);
if (sp == null)
{
client.SendTeleportFailed("Internal error");
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent not found in the scene where it is supposed to be");
return;
}
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: teleporting user {0} {1} home to {2} via {3}:{4}:{5}",
aCircuit.firstname, aCircuit.lastname, finalDestination.RegionName, homeGatekeeper.ExternalHostName, homeGatekeeper.HttpPort, homeGatekeeper.RegionName);
IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>();
DoTeleport(sp, homeGatekeeper, finalDestination, position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome), eq);
}
#endregion #endregion
private GridRegion MakeRegion(AgentCircuitData aCircuit)
{
GridRegion region = new GridRegion();
Uri uri = null;
if (!Uri.TryCreate(aCircuit.ServiceURLs["GatewayURI"].ToString(), UriKind.Absolute, out uri))
return null;
region.ExternalHostName = uri.Host;
region.HttpPort = (uint)uri.Port;
region.RegionName = string.Empty;
region.InternalEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("0.0.0.0"), (int)0);
return region;
}
} }
} }

View File

@ -62,7 +62,7 @@
<RegionModule id="InventoryServiceInConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsIn.Inventory.InventoryServiceInConnectorModule" /> <RegionModule id="InventoryServiceInConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsIn.Inventory.InventoryServiceInConnectorModule" />
<RegionModule id="LandServiceInConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsIn.Land.LandServiceInConnectorModule" /> <RegionModule id="LandServiceInConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsIn.Land.LandServiceInConnectorModule" />
<RegionModule id="NeighbourServiceInConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsIn.Neighbour.NeighbourServiceInConnectorModule" /> \ <RegionModule id="NeighbourServiceInConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsIn.Neighbour.NeighbourServiceInConnectorModule" /> \
<RegionModule id="HypergridServiceInConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsIn.Grid.HypergridServiceInConnectorModule" /> \ <RegionModule id="HypergridServiceInConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid.HypergridServiceInConnectorModule" /> \
<RegionModule id="LLLoginServiceInConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsIn.Login.LLLoginServiceInConnectorModule" /> \ <RegionModule id="LLLoginServiceInConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsIn.Login.LLLoginServiceInConnectorModule" /> \
<RegionModule id="SimulationServiceInConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsIn.Simulation.SimulationServiceInConnectorModule" /> \ <RegionModule id="SimulationServiceInConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsIn.Simulation.SimulationServiceInConnectorModule" /> \
<RegionModule id="GridInfoServiceInConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsIn.Grid.GridInfoServiceInConnectorModule" /> \ <RegionModule id="GridInfoServiceInConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsIn.Grid.GridInfoServiceInConnectorModule" /> \

View File

@ -40,7 +40,7 @@ using OpenSim.Server.Handlers.Hypergrid;
using OpenSim.Services.Interfaces; using OpenSim.Services.Interfaces;
using GridRegion = OpenSim.Services.Interfaces.GridRegion; using GridRegion = OpenSim.Services.Interfaces.GridRegion;
namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Grid namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
{ {
public class HypergridServiceInConnectorModule : ISharedRegionModule public class HypergridServiceInConnectorModule : ISharedRegionModule
{ {
@ -119,6 +119,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Grid
ISimulationService simService = scene.RequestModuleInterface<ISimulationService>(); ISimulationService simService = scene.RequestModuleInterface<ISimulationService>();
m_HypergridHandler = new GatekeeperServiceInConnector(m_Config, MainServer.Instance, simService); m_HypergridHandler = new GatekeeperServiceInConnector(m_Config, MainServer.Instance, simService);
//ServerUtils.LoadPlugin<HypergridServiceInConnector>("OpenSim.Server.Handlers.dll:HypergridServiceInConnector", args); //ServerUtils.LoadPlugin<HypergridServiceInConnector>("OpenSim.Server.Handlers.dll:HypergridServiceInConnector", args);
scene.RegisterModuleInterface<IGatekeeperService>(m_HypergridHandler.GateKeeper);
} }
} }

View File

@ -46,6 +46,12 @@ namespace OpenSim.Server.Handlers.Hypergrid
MethodBase.GetCurrentMethod().DeclaringType); MethodBase.GetCurrentMethod().DeclaringType);
private IGatekeeperService m_GatekeeperService; private IGatekeeperService m_GatekeeperService;
public IGatekeeperService GateKeeper
{
get { return m_GatekeeperService; }
}
private IHypergridService m_HypergridService;
public GatekeeperServiceInConnector(IConfigSource config, IHttpServer server, ISimulationService simService) : public GatekeeperServiceInConnector(IConfigSource config, IHttpServer server, ISimulationService simService) :
base(config, server, String.Empty) base(config, server, String.Empty)
@ -56,13 +62,19 @@ namespace OpenSim.Server.Handlers.Hypergrid
string serviceDll = gridConfig.GetString("LocalServiceModule", string.Empty); string serviceDll = gridConfig.GetString("LocalServiceModule", string.Empty);
Object[] args = new Object[] { config, simService }; Object[] args = new Object[] { config, simService };
m_GatekeeperService = ServerUtils.LoadPlugin<IGatekeeperService>(serviceDll, args); m_GatekeeperService = ServerUtils.LoadPlugin<IGatekeeperService>(serviceDll, args);
serviceDll = gridConfig.GetString("HypergridService", string.Empty);
m_HypergridService = ServerUtils.LoadPlugin<IHypergridService>(serviceDll, args);
} }
if (m_GatekeeperService == null) if (m_GatekeeperService == null || m_HypergridService == null)
throw new Exception("Gatekeeper server connector cannot proceed because of missing service"); throw new Exception("Gatekeeper server connector cannot proceed because of missing service");
HypergridHandlers hghandlers = new HypergridHandlers(m_GatekeeperService); HypergridHandlers hghandlers = new HypergridHandlers(m_GatekeeperService, m_HypergridService);
server.AddXmlRPCHandler("link_region", hghandlers.LinkRegionRequest, false); server.AddXmlRPCHandler("link_region", hghandlers.LinkRegionRequest, false);
server.AddXmlRPCHandler("link_region_by_desc", hghandlers.LinkRegionByDescRequest, false);
server.AddXmlRPCHandler("get_region", hghandlers.GetRegion, false); server.AddXmlRPCHandler("get_region", hghandlers.GetRegion, false);
server.AddXmlRPCHandler("get_home_region", hghandlers.GetHomeRegion, false);
server.AddHTTPHandler("/foreignagent/", new AgentHandler(m_GatekeeperService).Handler); server.AddHTTPHandler("/foreignagent/", new AgentHandler(m_GatekeeperService).Handler);

View File

@ -0,0 +1,122 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Reflection;
using Nini.Config;
using OpenSim.Framework;
using OpenSim.Server.Base;
using OpenSim.Services.Interfaces;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Server.Handlers.Base;
using log4net;
using Nwc.XmlRpc;
using OpenMetaverse;
namespace OpenSim.Server.Handlers.Hypergrid
{
public class HomeUsersSecurityServerConnector : ServiceConnector
{
private static readonly ILog m_log =
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
private IHomeUsersSecurityService m_HomeUsersService;
public HomeUsersSecurityServerConnector(IConfigSource config, IHttpServer server) :
base(config, server, String.Empty)
{
IConfig gridConfig = config.Configs["HomeUsersSecurityService"];
if (gridConfig != null)
{
string serviceDll = gridConfig.GetString("LocalServiceModule", string.Empty);
Object[] args = new Object[] { config };
m_HomeUsersService = ServerUtils.LoadPlugin<IHomeUsersSecurityService>(serviceDll, args);
}
if (m_HomeUsersService == null)
throw new Exception("HomeUsersSecurity server connector cannot proceed because of missing service");
server.AddXmlRPCHandler("ep_get", GetEndPoint, false);
server.AddXmlRPCHandler("ep_set", SetEndPoint, false);
server.AddXmlRPCHandler("ep_remove", RemoveEndPoint, false);
}
public XmlRpcResponse GetEndPoint(XmlRpcRequest request, IPEndPoint remoteClient)
{
Hashtable requestData = (Hashtable)request.Params[0];
//string host = (string)requestData["host"];
//string portstr = (string)requestData["port"];
string sessionID_str = (string)requestData["sessionID"];
UUID sessionID = UUID.Zero;
UUID.TryParse(sessionID_str, out sessionID);
IPEndPoint ep = m_HomeUsersService.GetEndPoint(sessionID);
Hashtable hash = new Hashtable();
if (ep == null)
hash["result"] = "false";
else
{
hash["result"] = "true";
hash["ep_addr"] = ep.Address.ToString();
hash["ep_port"] = ep.Port.ToString();
}
XmlRpcResponse response = new XmlRpcResponse();
response.Value = hash;
return response;
}
public XmlRpcResponse SetEndPoint(XmlRpcRequest request, IPEndPoint remoteClient)
{
Hashtable requestData = (Hashtable)request.Params[0];
string host = (string)requestData["ep_addr"];
string portstr = (string)requestData["ep_port"];
string sessionID_str = (string)requestData["sessionID"];
UUID sessionID = UUID.Zero;
UUID.TryParse(sessionID_str, out sessionID);
int port = 0;
Int32.TryParse(portstr, out port);
IPEndPoint ep = null;
try
{
ep = new IPEndPoint(IPAddress.Parse(host), port);
}
catch
{
m_log.Debug("[HOME USERS SECURITY]: Exception in creating EndPoint");
}
m_HomeUsersService.SetEndPoint(sessionID, ep);
Hashtable hash = new Hashtable();
hash["result"] = "true";
XmlRpcResponse response = new XmlRpcResponse();
response.Value = hash;
return response;
}
public XmlRpcResponse RemoveEndPoint(XmlRpcRequest request, IPEndPoint remoteClient)
{
Hashtable requestData = (Hashtable)request.Params[0];
string sessionID_str = (string)requestData["sessionID"];
UUID sessionID = UUID.Zero;
UUID.TryParse(sessionID_str, out sessionID);
m_HomeUsersService.RemoveEndPoint(sessionID);
Hashtable hash = new Hashtable();
hash["result"] = "true";
XmlRpcResponse response = new XmlRpcResponse();
response.Value = hash;
return response;
}
}
}

View File

@ -44,10 +44,12 @@ namespace OpenSim.Server.Handlers.Hypergrid
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private IGatekeeperService m_GatekeeperService; private IGatekeeperService m_GatekeeperService;
private IHypergridService m_HypergridService;
public HypergridHandlers(IGatekeeperService gatekeeper) public HypergridHandlers(IGatekeeperService gatekeeper, IHypergridService hyper)
{ {
m_GatekeeperService = gatekeeper; m_GatekeeperService = gatekeeper;
m_HypergridService = hyper;
} }
/// <summary> /// <summary>
@ -80,6 +82,36 @@ namespace OpenSim.Server.Handlers.Hypergrid
return response; return response;
} }
/// <summary>
/// A local region wants to establish a grid-wide hyperlink to another region
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public XmlRpcResponse LinkRegionByDescRequest(XmlRpcRequest request, IPEndPoint remoteClient)
{
Hashtable requestData = (Hashtable)request.Params[0];
//string host = (string)requestData["host"];
//string portstr = (string)requestData["port"];
string descriptor = (string)requestData["region_desc"];
UUID regionID = UUID.Zero;
string imageURL = string.Empty;
ulong regionHandle = 0;
string reason = string.Empty;
bool success = m_HypergridService.LinkRegion(descriptor, out regionID, out regionHandle, out imageURL, out reason);
Hashtable hash = new Hashtable();
hash["result"] = success.ToString();
hash["uuid"] = regionID.ToString();
hash["handle"] = regionHandle.ToString();
hash["region_image"] = imageURL;
XmlRpcResponse response = new XmlRpcResponse();
response.Value = hash;
return response;
}
public XmlRpcResponse GetRegion(XmlRpcRequest request, IPEndPoint remoteClient) public XmlRpcResponse GetRegion(XmlRpcRequest request, IPEndPoint remoteClient)
{ {
Hashtable requestData = (Hashtable)request.Params[0]; Hashtable requestData = (Hashtable)request.Params[0];
@ -111,5 +143,38 @@ namespace OpenSim.Server.Handlers.Hypergrid
} }
public XmlRpcResponse GetHomeRegion(XmlRpcRequest request, IPEndPoint remoteClient)
{
Hashtable requestData = (Hashtable)request.Params[0];
//string host = (string)requestData["host"];
//string portstr = (string)requestData["port"];
string userID_str = (string)requestData["userID"];
UUID userID = UUID.Zero;
UUID.TryParse(userID_str, out userID);
Vector3 position = Vector3.UnitY, lookAt = Vector3.UnitY;
GridRegion regInfo = m_GatekeeperService.GetHomeRegion(userID, out position, out lookAt);
Hashtable hash = new Hashtable();
if (regInfo == null)
hash["result"] = "false";
else
{
hash["result"] = "true";
hash["uuid"] = regInfo.RegionID.ToString();
hash["x"] = regInfo.RegionLocX.ToString();
hash["y"] = regInfo.RegionLocY.ToString();
hash["region_name"] = regInfo.RegionName;
hash["hostname"] = regInfo.ExternalHostName;
hash["http_port"] = regInfo.HttpPort.ToString();
hash["internal_port"] = regInfo.InternalEndPoint.Port.ToString();
hash["position"] = position.ToString();
hash["lookAt"] = lookAt.ToString();
}
XmlRpcResponse response = new XmlRpcResponse();
response.Value = hash;
return response;
}
} }
} }

View File

@ -0,0 +1,119 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using OpenSim.Services.Interfaces;
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
using OpenMetaverse;
using Nwc.XmlRpc;
using OpenSim.Services.Connectors.Simulation;
namespace OpenSim.Services.Connectors.Hypergrid
{
public class GatekeeperServiceConnector : SimulationServiceConnector
{
protected override string AgentPath()
{
return "/foreignagent/";
}
protected override string ObjectPath()
{
return "/foreignobject/";
}
public GridRegion GetHomeRegion(GridRegion gatekeeper, UUID userID, out Vector3 position, out Vector3 lookAt)
{
position = Vector3.UnitY; lookAt = Vector3.UnitY;
Hashtable hash = new Hashtable();
hash["userID"] = userID.ToString();
IList paramList = new ArrayList();
paramList.Add(hash);
XmlRpcRequest request = new XmlRpcRequest("get_home_region", paramList);
string uri = "http://" + gatekeeper.ExternalHostName + ":" + gatekeeper.HttpPort + "/";
XmlRpcResponse response = null;
try
{
response = request.Send(uri, 10000);
}
catch (Exception e)
{
return null;
}
if (response.IsFault)
{
return null;
}
hash = (Hashtable)response.Value;
//foreach (Object o in hash)
// m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
try
{
bool success = false;
Boolean.TryParse((string)hash["result"], out success);
if (success)
{
GridRegion region = new GridRegion();
UUID.TryParse((string)hash["uuid"], out region.RegionID);
//m_log.Debug(">> HERE, uuid: " + region.RegionID);
int n = 0;
if (hash["x"] != null)
{
Int32.TryParse((string)hash["x"], out n);
region.RegionLocX = n;
//m_log.Debug(">> HERE, x: " + region.RegionLocX);
}
if (hash["y"] != null)
{
Int32.TryParse((string)hash["y"], out n);
region.RegionLocY = n;
//m_log.Debug(">> HERE, y: " + region.RegionLocY);
}
if (hash["region_name"] != null)
{
region.RegionName = (string)hash["region_name"];
//m_log.Debug(">> HERE, name: " + region.RegionName);
}
if (hash["hostname"] != null)
region.ExternalHostName = (string)hash["hostname"];
if (hash["http_port"] != null)
{
uint p = 0;
UInt32.TryParse((string)hash["http_port"], out p);
region.HttpPort = p;
}
if (hash["internal_port"] != null)
{
int p = 0;
Int32.TryParse((string)hash["internal_port"], out p);
region.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), p);
}
if (hash["position"] != null)
Vector3.TryParse((string)hash["position"], out position);
if (hash["lookAt"] != null)
Vector3.TryParse((string)hash["lookAt"], out lookAt);
// Successful return
return region;
}
}
catch (Exception e)
{
return null;
}
return null;
}
}
}

View File

@ -0,0 +1,132 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Reflection;
using OpenSim.Services.Interfaces;
using OpenMetaverse;
using log4net;
using Nwc.XmlRpc;
using Nini.Config;
namespace OpenSim.Services.Connectors.Hypergrid
{
public class HomeUsersSecurityServiceConnector : IHomeUsersSecurityService
{
private static readonly ILog m_log =
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
string m_ServerURL;
public HomeUsersSecurityServiceConnector(string url)
{
m_ServerURL = url;
}
public HomeUsersSecurityServiceConnector(IConfigSource config)
{
}
public void SetEndPoint(UUID sessionID, IPEndPoint ep)
{
Hashtable hash = new Hashtable();
hash["sessionID"] = sessionID.ToString();
hash["ep_addr"] = ep.Address.ToString();
hash["ep_port"] = ep.Port.ToString();
Call("ep_set", hash);
}
public void RemoveEndPoint(UUID sessionID)
{
Hashtable hash = new Hashtable();
hash["sessionID"] = sessionID.ToString();
Call("ep_remove", hash);
}
public IPEndPoint GetEndPoint(UUID sessionID)
{
Hashtable hash = new Hashtable();
hash["sessionID"] = sessionID.ToString();
IList paramList = new ArrayList();
paramList.Add(hash);
XmlRpcRequest request = new XmlRpcRequest("ep_get", paramList);
//m_log.Debug("[HGrid]: Linking to " + uri);
XmlRpcResponse response = null;
try
{
response = request.Send(m_ServerURL, 10000);
}
catch (Exception e)
{
m_log.Debug("[HGrid]: Exception " + e.Message);
return null;
}
if (response.IsFault)
{
m_log.ErrorFormat("[HGrid]: remote call returned an error: {0}", response.FaultString);
return null;
}
hash = (Hashtable)response.Value;
//foreach (Object o in hash)
// m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
try
{
bool success = false;
Boolean.TryParse((string)hash["result"], out success);
if (success)
{
IPEndPoint ep = null;
int port = 0;
if (hash["ep_port"] != null)
Int32.TryParse((string)hash["ep_port"], out port);
if (hash["ep_addr"] != null)
ep = new IPEndPoint(IPAddress.Parse((string)hash["ep_addr"]), port);
return ep;
}
}
catch (Exception e)
{
m_log.Error("[HGrid]: Got exception while parsing GetEndPoint response " + e.StackTrace);
return null;
}
return null;
}
private void Call(string method, Hashtable hash)
{
IList paramList = new ArrayList();
paramList.Add(hash);
XmlRpcRequest request = new XmlRpcRequest(method, paramList);
XmlRpcResponse response = null;
try
{
response = request.Send(m_ServerURL, 10000);
}
catch (Exception e)
{
m_log.Debug("[HGrid]: Exception " + e.Message);
return ;
}
if (response.IsFault)
{
m_log.ErrorFormat("[HGrid]: remote call returned an error: {0}", response.FaultString);
return ;
}
}
}
}

View File

@ -41,22 +41,49 @@ using OpenMetaverse;
using OpenMetaverse.Imaging; using OpenMetaverse.Imaging;
using log4net; using log4net;
using Nwc.XmlRpc; using Nwc.XmlRpc;
using Nini.Config;
namespace OpenSim.Services.Connectors.Hypergrid namespace OpenSim.Services.Connectors.Hypergrid
{ {
public class HypergridServiceConnector public class HypergridServiceConnector : IHypergridService
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private IAssetService m_AssetService; private IAssetService m_AssetService;
private string m_ServerURL;
public HypergridServiceConnector() : this(null) { } public HypergridServiceConnector() { }
public HypergridServiceConnector(IAssetService assService) public HypergridServiceConnector(IAssetService assService)
{ {
m_AssetService = assService; m_AssetService = assService;
} }
public HypergridServiceConnector(IConfigSource source)
{
Initialise(source);
}
public virtual void Initialise(IConfigSource source)
{
IConfig hgConfig = source.Configs["HypergridService"];
if (hgConfig == null)
{
m_log.Error("[HYPERGRID CONNECTOR]: HypergridService missing from OpenSim.ini");
throw new Exception("Hypergrid connector init error");
}
string serviceURI = hgConfig.GetString("HypergridServerURI",
String.Empty);
if (serviceURI == String.Empty)
{
m_log.Error("[HYPERGRID CONNECTOR]: No Server URI named in section HypergridService");
throw new Exception("Hypergrid connector init error");
}
m_ServerURL = serviceURI;
}
public bool LinkRegion(GridRegion info, out UUID regionID, out ulong realHandle, out string imageURL, out string reason) public bool LinkRegion(GridRegion info, out UUID regionID, out ulong realHandle, out string imageURL, out string reason)
{ {
regionID = UUID.Zero; regionID = UUID.Zero;
@ -246,5 +273,82 @@ namespace OpenSim.Services.Connectors.Hypergrid
return null; return null;
} }
#region From local regions to grid-wide hypergrid service
public bool LinkRegion(string regionDescriptor, out UUID regionID, out ulong realHandle, out string imageURL, out string reason)
{
regionID = UUID.Zero;
imageURL = string.Empty;
realHandle = 0;
reason = string.Empty;
Hashtable hash = new Hashtable();
hash["region_desc"] = regionDescriptor;
IList paramList = new ArrayList();
paramList.Add(hash);
XmlRpcRequest request = new XmlRpcRequest("link_region_by_desc", paramList);
XmlRpcResponse response = null;
try
{
response = request.Send(m_ServerURL, 10000);
}
catch (Exception e)
{
m_log.Debug("[HGrid]: Exception " + e.Message);
reason = "Error contacting remote server";
return false;
}
if (response.IsFault)
{
reason = response.FaultString;
m_log.ErrorFormat("[HGrid]: remote call returned an error: {0}", response.FaultString);
return false;
}
hash = (Hashtable)response.Value;
//foreach (Object o in hash)
// m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
try
{
bool success = false;
Boolean.TryParse((string)hash["result"], out success);
if (success)
{
UUID.TryParse((string)hash["uuid"], out regionID);
//m_log.Debug(">> HERE, uuid: " + uuid);
if ((string)hash["handle"] != null)
{
realHandle = Convert.ToUInt64((string)hash["handle"]);
//m_log.Debug(">> HERE, realHandle: " + realHandle);
}
if (hash["region_image"] != null)
{
imageURL = (string)hash["region_image"];
}
}
}
catch (Exception e)
{
reason = "Error parsing return arguments";
m_log.Error("[HGrid]: Got exception while parsing hyperlink response " + e.StackTrace);
return false;
}
return true;
}
// TODO !!!
public GridRegion GetRegionByUUID(UUID regionID) { return null; }
public GridRegion GetRegionByPosition(int x, int y) { return null; }
public GridRegion GetRegionByName(string name) { return null; }
public List<GridRegion> GetRegionsByName(string name) { return null; }
public List<GridRegion> GetRegionRange(int xmin, int xmax, int ymin, int ymax) { return null; }
#endregion
} }
} }

View File

@ -27,6 +27,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Net;
using System.Reflection; using System.Reflection;
using OpenSim.Framework; using OpenSim.Framework;
@ -51,6 +52,7 @@ namespace OpenSim.Services.HypergridService
IPresenceService m_PresenceService; IPresenceService m_PresenceService;
IAuthenticationService m_AuthenticationService; IAuthenticationService m_AuthenticationService;
IUserAccountService m_UserAccountService; IUserAccountService m_UserAccountService;
IHomeUsersSecurityService m_HomeUsersSecurityService;
ISimulationService m_SimulationService; ISimulationService m_SimulationService;
string m_AuthDll; string m_AuthDll;
@ -66,14 +68,15 @@ namespace OpenSim.Services.HypergridService
throw new Exception(String.Format("No section GatekeeperService in config file")); throw new Exception(String.Format("No section GatekeeperService in config file"));
string accountService = serverConfig.GetString("UserAccountService", String.Empty); string accountService = serverConfig.GetString("UserAccountService", String.Empty);
string homeUsersSecurityService = serverConfig.GetString("HomeUsersSecurityService", string.Empty);
string gridService = serverConfig.GetString("GridService", String.Empty); string gridService = serverConfig.GetString("GridService", String.Empty);
string presenceService = serverConfig.GetString("PresenceService", String.Empty); string presenceService = serverConfig.GetString("PresenceService", String.Empty);
string simulationService = serverConfig.GetString("SimulationService", String.Empty); string simulationService = serverConfig.GetString("SimulationService", String.Empty);
m_AuthDll = serverConfig.GetString("AuthenticationService", String.Empty); m_AuthDll = serverConfig.GetString("AuthenticationService", String.Empty);
if (accountService == string.Empty || gridService == string.Empty || // These 3 are mandatory, the others aren't
presenceService == string.Empty || m_AuthDll == string.Empty) if (gridService == string.Empty || presenceService == string.Empty || m_AuthDll == string.Empty)
throw new Exception("Incomplete specifications, Gatekeeper Service cannot function."); throw new Exception("Incomplete specifications, Gatekeeper Service cannot function.");
string scope = serverConfig.GetString("ScopeID", UUID.Zero.ToString()); string scope = serverConfig.GetString("ScopeID", UUID.Zero.ToString());
@ -82,16 +85,20 @@ namespace OpenSim.Services.HypergridService
m_AllowTeleportsToAnyRegion = serverConfig.GetBoolean("AllowTeleportsToAnyRegion", true); m_AllowTeleportsToAnyRegion = serverConfig.GetBoolean("AllowTeleportsToAnyRegion", true);
Object[] args = new Object[] { config }; Object[] args = new Object[] { config };
m_UserAccountService = ServerUtils.LoadPlugin<IUserAccountService>(accountService, args);
m_GridService = ServerUtils.LoadPlugin<IGridService>(gridService, args); m_GridService = ServerUtils.LoadPlugin<IGridService>(gridService, args);
m_PresenceService = ServerUtils.LoadPlugin<IPresenceService>(presenceService, args); m_PresenceService = ServerUtils.LoadPlugin<IPresenceService>(presenceService, args);
if (accountService != string.Empty)
m_UserAccountService = ServerUtils.LoadPlugin<IUserAccountService>(accountService, args);
if (homeUsersSecurityService != string.Empty)
m_HomeUsersSecurityService = ServerUtils.LoadPlugin<IHomeUsersSecurityService>(homeUsersSecurityService, args);
if (simService != null) if (simService != null)
m_SimulationService = simService; m_SimulationService = simService;
else if (simulationService != string.Empty) else if (simulationService != string.Empty)
m_SimulationService = ServerUtils.LoadPlugin<ISimulationService>(simulationService, args); m_SimulationService = ServerUtils.LoadPlugin<ISimulationService>(simulationService, args);
if (m_UserAccountService == null || m_GridService == null || if (m_GridService == null || m_PresenceService == null || m_SimulationService == null)
m_PresenceService == null || m_SimulationService == null)
throw new Exception("Unable to load a required plugin, Gatekeeper Service cannot function."); throw new Exception("Unable to load a required plugin, Gatekeeper Service cannot function.");
m_log.Debug("[GATEKEEPER SERVICE]: Starting..."); m_log.Debug("[GATEKEEPER SERVICE]: Starting...");
@ -164,6 +171,7 @@ namespace OpenSim.Services.HypergridService
return region; return region;
} }
#region Login Agent
public bool LoginAgent(AgentCircuitData aCircuit, GridRegion destination, out string reason) public bool LoginAgent(AgentCircuitData aCircuit, GridRegion destination, out string reason)
{ {
reason = string.Empty; reason = string.Empty;
@ -174,6 +182,9 @@ namespace OpenSim.Services.HypergridService
m_log.DebugFormat("[GATEKEEPER SERVICE]: Request to login foreign agent {0} {1} @ {2} ({3}) at destination {4}", m_log.DebugFormat("[GATEKEEPER SERVICE]: Request to login foreign agent {0} {1} @ {2} ({3}) at destination {4}",
aCircuit.firstname, aCircuit.lastname, authURL, aCircuit.AgentID, destination.RegionName); aCircuit.firstname, aCircuit.lastname, authURL, aCircuit.AgentID, destination.RegionName);
//
// Authenticate the user
//
if (!Authenticate(aCircuit)) if (!Authenticate(aCircuit))
{ {
reason = "Unable to verify identity"; reason = "Unable to verify identity";
@ -181,22 +192,40 @@ namespace OpenSim.Services.HypergridService
return false; return false;
} }
m_log.DebugFormat("[GATEKEEPER SERVICE]: Identity verified for {0} {1} @ {2}", aCircuit.firstname, aCircuit.lastname, authURL); m_log.DebugFormat("[GATEKEEPER SERVICE]: Identity verified for {0} {1} @ {2}", aCircuit.firstname, aCircuit.lastname, authURL);
// Check to see if we have a local user with that UUID //
UserAccount account = m_UserAccountService.GetUserAccount(m_ScopeID, aCircuit.AgentID); // Check for impersonations
if (account != null) //
UserAccount account = null;
if (m_UserAccountService != null)
{ {
// No, sorry; go away // Check to see if we have a local user with that UUID
reason = "User identifier not allowed on this grid"; account = m_UserAccountService.GetUserAccount(m_ScopeID, aCircuit.AgentID);
m_log.InfoFormat("[GATEKEEPER SERVICE]: Foreign agent {0} {1} has UUID of local user {3}. Refusing service.", if (account != null)
aCircuit.firstname, aCircuit.lastname, aCircuit.AgentID); {
return false; // Make sure this is the user coming home, and not a fake
if (m_HomeUsersSecurityService != null)
{
Object ep = m_HomeUsersSecurityService.GetEndPoint(aCircuit.SessionID);
if (ep == null)
{
// This is a fake, this session never left this grid
reason = "Unauthorized";
m_log.InfoFormat("[GATEKEEPER SERVICE]: Foreign agent {0} {1} has same ID as local user. Refusing service.",
aCircuit.firstname, aCircuit.lastname);
return false;
}
}
}
} }
m_log.DebugFormat("[GATEKEEPER SERVICE]: User ID ok"); m_log.DebugFormat("[GATEKEEPER SERVICE]: User is ok");
// May want to authorize // May want to authorize
//
// Login the presence // Login the presence
//
if (!m_PresenceService.LoginAgent(aCircuit.AgentID.ToString(), aCircuit.SessionID, aCircuit.SecureSessionID)) if (!m_PresenceService.LoginAgent(aCircuit.AgentID.ToString(), aCircuit.SessionID, aCircuit.SecureSessionID))
{ {
reason = "Unable to login presence"; reason = "Unable to login presence";
@ -206,22 +235,38 @@ namespace OpenSim.Services.HypergridService
} }
m_log.DebugFormat("[GATEKEEPER SERVICE]: Login presence ok"); m_log.DebugFormat("[GATEKEEPER SERVICE]: Login presence ok");
//
// Get the region // Get the region
//
destination = m_GridService.GetRegionByUUID(m_ScopeID, destination.RegionID); destination = m_GridService.GetRegionByUUID(m_ScopeID, destination.RegionID);
if (destination == null) if (destination == null)
{ {
reason = "Destination region not found"; reason = "Destination region not found";
return false; return false;
} }
m_log.DebugFormat("[GATEKEEPER SERVICE]: destination ok : {0}", destination.RegionName); m_log.DebugFormat("[GATEKEEPER SERVICE]: destination ok: {0}", destination.RegionName);
//
// Adjust the visible name
//
if (account != null)
{
aCircuit.firstname = account.FirstName;
aCircuit.lastname = account.LastName;
}
if (account == null && !aCircuit.lastname.StartsWith("@"))
{
aCircuit.firstname = aCircuit.firstname + "." + aCircuit.lastname;
aCircuit.lastname = "@" + aCircuit.ServiceURLs["HomeURI"].ToString();
}
//
// Finally launch the agent at the destination // Finally launch the agent at the destination
aCircuit.firstname = aCircuit.firstname + "." + aCircuit.lastname; //
aCircuit.lastname = "@" + aCircuit.ServiceURLs["HomeURI"].ToString();
return m_SimulationService.CreateAgent(destination, aCircuit, 0, out reason); return m_SimulationService.CreateAgent(destination, aCircuit, 0, out reason);
} }
protected bool Authenticate(AgentCircuitData aCircuit) protected bool Authenticate(AgentCircuitData aCircuit)
{ {
string authURL = string.Empty; string authURL = string.Empty;
if (aCircuit.ServiceURLs.ContainsKey("HomeURI")) if (aCircuit.ServiceURLs.ContainsKey("HomeURI"))
@ -250,5 +295,40 @@ namespace OpenSim.Services.HypergridService
return false; return false;
} }
#endregion
public GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt)
{
position = new Vector3(128, 128, 0); lookAt = Vector3.UnitY;
m_log.DebugFormat("[GATEKEEPER SERVICE]: Request to get home region of user {0}", userID);
GridRegion home = null;
PresenceInfo[] presences = m_PresenceService.GetAgents(new string[] { userID.ToString() });
if (presences != null && presences.Length > 0)
{
UUID homeID = presences[0].HomeRegionID;
if (homeID != UUID.Zero)
{
home = m_GridService.GetRegionByUUID(m_ScopeID, homeID);
position = presences[0].HomePosition;
lookAt = presences[0].HomeLookAt;
}
if (home == null)
{
List<GridRegion> defs = m_GridService.GetDefaultRegions(m_ScopeID);
if (defs != null && defs.Count > 0)
home = defs[0];
}
}
return home;
}
#region Misc
#endregion
} }
} }

View File

@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Reflection;
using OpenSim.Services.Interfaces;
using OpenMetaverse;
using log4net;
using Nini.Config;
namespace OpenSim.Services.HypergridService
{
/// <summary>
/// This service is for HG1.5 only, to make up for the fact that clients don't
/// keep any private information in themselves, and that their 'home service'
/// needs to do it for them.
/// Once we have better clients, this shouldn't be needed.
/// </summary>
public class HomeUsersSecurityService : IHomeUsersSecurityService
{
private static readonly ILog m_log =
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
//
// This is a persistent storage wannabe for dealing with the
// quirks of HG1.5. We don't really want to store this in a table.
// But this is the necessary information for securing clients
// coming home.
//
protected static Dictionary<UUID, IPEndPoint> m_ClientEndPoints = new Dictionary<UUID, IPEndPoint>();
public HomeUsersSecurityService(IConfigSource config)
{
m_log.DebugFormat("[HOME USERS SECURITY]: Starting...");
}
public void SetEndPoint(UUID sessionID, IPEndPoint ep)
{
m_log.DebugFormat("[HOME USERS SECURITY]: Set EndPoint {0} for session {1}", ep.ToString(), sessionID);
lock (m_ClientEndPoints)
m_ClientEndPoints[sessionID] = ep;
}
public IPEndPoint GetEndPoint(UUID sessionID)
{
lock (m_ClientEndPoints)
if (m_ClientEndPoints.ContainsKey(sessionID))
{
m_log.DebugFormat("[HOME USERS SECURITY]: Get EndPoint {0} for session {1}", m_ClientEndPoints[sessionID].ToString(), sessionID);
return m_ClientEndPoints[sessionID];
}
return null;
}
public void RemoveEndPoint(UUID sessionID)
{
m_log.DebugFormat("[HOME USERS SECURITY]: Remove EndPoint for session {0}", sessionID);
lock (m_ClientEndPoints)
if (m_ClientEndPoints.ContainsKey(sessionID))
m_ClientEndPoints.Remove(sessionID);
}
}
}

View File

@ -51,7 +51,7 @@ namespace OpenSim.Services.HypergridService
private static HypergridService m_RootInstance = null; private static HypergridService m_RootInstance = null;
protected IConfigSource m_config; protected IConfigSource m_config;
protected IAuthenticationService m_AuthenticationService = null; protected IPresenceService m_PresenceService = null;
protected IGridService m_GridService; protected IGridService m_GridService;
protected IAssetService m_AssetService; protected IAssetService m_AssetService;
protected HypergridServiceConnector m_HypergridConnector; protected HypergridServiceConnector m_HypergridConnector;
@ -94,7 +94,7 @@ namespace OpenSim.Services.HypergridService
if (gridConfig != null) if (gridConfig != null)
{ {
string gridService = gridConfig.GetString("GridService", string.Empty); string gridService = gridConfig.GetString("GridService", string.Empty);
string authService = gridConfig.GetString("AuthenticationService", String.Empty); string presenceService = gridConfig.GetString("PresenceService", String.Empty);
string assetService = gridConfig.GetString("AssetService", string.Empty); string assetService = gridConfig.GetString("AssetService", string.Empty);
Object[] args = new Object[] { config }; Object[] args = new Object[] { config };
@ -104,8 +104,8 @@ namespace OpenSim.Services.HypergridService
if (m_GridService == null) if (m_GridService == null)
throw new Exception("HypergridService cannot function without a GridService"); throw new Exception("HypergridService cannot function without a GridService");
if (authService != String.Empty) if (presenceService != String.Empty)
m_AuthenticationService = ServerUtils.LoadPlugin<IAuthenticationService>(authService, args); m_PresenceService = ServerUtils.LoadPlugin<IPresenceService>(presenceService, args);
if (assetService != string.Empty) if (assetService != string.Empty)
m_AssetService = ServerUtils.LoadPlugin<IAssetService>(assetService, args); m_AssetService = ServerUtils.LoadPlugin<IAssetService>(assetService, args);

View File

@ -26,6 +26,7 @@
*/ */
using System; using System;
using System.Net;
using System.Collections.Generic; using System.Collections.Generic;
using OpenSim.Framework; using OpenSim.Framework;
@ -39,5 +40,18 @@ namespace OpenSim.Services.Interfaces
GridRegion GetHyperlinkRegion(UUID regionID); GridRegion GetHyperlinkRegion(UUID regionID);
bool LoginAgent(AgentCircuitData aCircuit, GridRegion destination, out string reason); bool LoginAgent(AgentCircuitData aCircuit, GridRegion destination, out string reason);
GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt);
}
/// <summary>
/// HG1.5 only
/// </summary>
public interface IHomeUsersSecurityService
{
void SetEndPoint(UUID sessionID, IPEndPoint ep);
IPEndPoint GetEndPoint(UUID sessionID);
void RemoveEndPoint(UUID sessionID);
} }
} }

View File

@ -43,6 +43,7 @@ namespace OpenSim.Services.Interfaces
GridRegion GetRegionByName(string name); GridRegion GetRegionByName(string name);
List<GridRegion> GetRegionsByName(string name); List<GridRegion> GetRegionsByName(string name);
List<GridRegion> GetRegionRange(int xmin, int xmax, int ymin, int ymax); List<GridRegion> GetRegionRange(int xmin, int xmax, int ymin, int ymax);
} }
} }

View File

@ -42,7 +42,6 @@ ServiceConnectors = "OpenSim.Server.Handlers.dll:AssetServiceConnector,OpenSim.S
; * ; *
[InventoryService] [InventoryService]
LocalServiceModule = "OpenSim.Services.InventoryService.dll:InventoryService" LocalServiceModule = "OpenSim.Services.InventoryService.dll:InventoryService"
UserServerURI = "http://127.0.0.1:8002"
SessionAuthentication = "false" SessionAuthentication = "false"
StorageProvider = "OpenSim.Data.MySQL.dll" StorageProvider = "OpenSim.Data.MySQL.dll"
ConnectionString = "Data Source=localhost;Database=opensim;User ID=opensim;Password=opensim123;" ConnectionString = "Data Source=localhost;Database=opensim;User ID=opensim;Password=opensim123;"
@ -58,10 +57,12 @@ ServiceConnectors = "OpenSim.Server.Handlers.dll:AssetServiceConnector,OpenSim.S
Realm = "regions" Realm = "regions"
; AllowDuplicateNames = "True" ; AllowDuplicateNames = "True"
;; Next, we can specify properties of regions, including default and fallback regions ;; Next, we can specify properties of regions, including default and fallback regions
;; The syntax is: Region_<RegioName> = "<flags>" ;; The syntax is: Region_<RegionName> = "<flags>"
;; or: Region_<RegionID> = "<flags>"
;; where <flags> can be DefaultRegion, FallbackRegion, NoDirectLogin, Persistent, LockedOut,Reservation,NoMove,Authenticate ;; where <flags> can be DefaultRegion, FallbackRegion, NoDirectLogin, Persistent, LockedOut,Reservation,NoMove,Authenticate
;; For example: ;; For example:
; Region_Welcome_Area = "DefaultRegion, FallbackRegion" ; Region_Welcome_Area = "DefaultRegion, FallbackRegion"
; (replace spaces with underscore)
; * This is the configuration for the freeswitch server in grid mode ; * This is the configuration for the freeswitch server in grid mode
[FreeswitchService] [FreeswitchService]

View File

@ -17,18 +17,17 @@
AvatarServices = "RemoteAvatarServicesConnector" AvatarServices = "RemoteAvatarServicesConnector"
NeighbourServices = "RemoteNeighbourServicesConnector" NeighbourServices = "RemoteNeighbourServicesConnector"
AuthenticationServices = "RemoteAuthenticationServicesConnector" AuthenticationServices = "RemoteAuthenticationServicesConnector"
AuthorizationServices = "LocalAuthorizationServicesConnector"
PresenceServices = "RemotePresenceServicesConnector" PresenceServices = "RemotePresenceServicesConnector"
UserAccountServices = "RemoteUserAccountServicesConnector" UserAccountServices = "RemoteUserAccountServicesConnector"
SimulationServices = "RemoteSimulationConnectorModule" SimulationServices = "RemoteSimulationConnectorModule"
EntityTransferModule = "BasicEntityTransferModule" EntityTransferModule = "HGEntityTransferModule"
LandServiceInConnector = true LandServiceInConnector = true
NeighbourServiceInConnector = true NeighbourServiceInConnector = true
HypergridServiceInConnector = true
SimulationServiceInConnector = true SimulationServiceInConnector = true
LibraryModule = true LibraryModule = true
InventoryServiceInConnector = false InventoryServiceInConnector = false
AssetServiceInConnector = false AssetServiceInConnector = false
LLLoginServiceInConnector = false
[AssetService] [AssetService]
LocalGridAssetService = "OpenSim.Services.Connectors.dll:AssetServicesConnector" LocalGridAssetService = "OpenSim.Services.Connectors.dll:AssetServicesConnector"
@ -41,12 +40,12 @@
[GridService] [GridService]
; for the HGGridServicesConnector to instantiate ; for the HGGridServicesConnector to instantiate
GridServiceConnectorModule = "OpenSim.Region.CoreModules.dll:RemoteGridServicesConnector" GridServiceConnectorModule = "OpenSim.Region.CoreModules.dll:RemoteGridServicesConnector"
HypergridService = "OpenSim.Services.HypergridService.dll:HypergridService"
; RemoteGridServicesConnector instantiates a LocalGridServicesConnector, ; RemoteGridServicesConnector instantiates a LocalGridServicesConnector,
; which in turn uses this ; which in turn uses this
LocalServiceModule = "OpenSim.Services.GridService.dll:GridService" LocalServiceModule = "OpenSim.Services.GridService.dll:GridService"
StorageProvider = "OpenSim.Data.Null.dll:NullRegionData" StorageProvider = "OpenSim.Data.Null.dll:NullRegionData"
[LibraryService] [HypergridService]
LocalServiceModule = "OpenSim.Services.InventoryService.dll:LibraryService" GridService = "OpenSim.Services.GridService.dll:GridService"
LibraryName = "OpenSim Library" AssetService = "OpenSim.Services.AssetService.dll:AssetService"
DefaultLibrary = "./inventory/Libraries.xml"

View File

@ -82,6 +82,9 @@
GridService = "OpenSim.Services.GridService.dll:GridService" GridService = "OpenSim.Services.GridService.dll:GridService"
AuthenticationService = "OpenSim.Services.Connectors.dll:AuthenticationServicesConnector" AuthenticationService = "OpenSim.Services.Connectors.dll:AuthenticationServicesConnector"
[HGEntityTransferModule]
HomeUsersSecurityService = "OpenSim.Services.HypergridService.dll:HomeUsersSecurityService"
[PresenceService] [PresenceService]
LocalServiceModule = "OpenSim.Services.PresenceService.dll:PresenceService" LocalServiceModule = "OpenSim.Services.PresenceService.dll:PresenceService"