* Little more spring cleaning.

0.6.0-stable
Adam Frisby 2008-04-29 14:10:26 +00:00
parent 375163a6fe
commit de2ff8e626
6 changed files with 481 additions and 383 deletions

View File

@ -43,6 +43,8 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
#region IApplicationPlugin Members
public void Initialise(OpenSimMain openSim) public void Initialise(OpenSimMain openSim)
{ {
m_log.Info("[LOADREGIONS]: Load Regions addin being initialised"); m_log.Info("[LOADREGIONS]: Load Regions addin being initialised");
@ -66,14 +68,21 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
for (int i = 0; i < regionsToLoad.Length; i++) for (int i = 0; i < regionsToLoad.Length; i++)
{ {
m_log.Debug("[LOADREGIONS]: Creating Region: " + regionsToLoad[i].RegionName + " (ThreadID: " + Thread.CurrentThread.ManagedThreadId.ToString() + ")"); m_log.Debug("[LOADREGIONS]: Creating Region: " + regionsToLoad[i].RegionName + " (ThreadID: " + Thread.CurrentThread.ManagedThreadId.ToString() +
openSim.CreateRegion(regionsToLoad[i], true); ")");
openSim.CreateRegion(regionsToLoad[i], true);
} }
openSim.ModuleLoader.PostInitialise(); openSim.ModuleLoader.PostInitialise();
openSim.ModuleLoader.ClearCache(); openSim.ModuleLoader.ClearCache();
} }
public void Close()
{
}
#endregion
public void LoadRegionFromConfig(OpenSimMain openSim, ulong regionhandle) public void LoadRegionFromConfig(OpenSimMain openSim, ulong regionhandle)
{ {
m_log.Info("[LOADREGIONS]: Load Regions addin being initialised"); m_log.Info("[LOADREGIONS]: Load Regions addin being initialised");
@ -96,14 +105,11 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
{ {
if (regionhandle == regionsToLoad[i].RegionHandle) if (regionhandle == regionsToLoad[i].RegionHandle)
{ {
m_log.Debug("[LOADREGIONS]: Creating Region: " + regionsToLoad[i].RegionName + " (ThreadID: " + Thread.CurrentThread.ManagedThreadId.ToString() + ")"); m_log.Debug("[LOADREGIONS]: Creating Region: " + regionsToLoad[i].RegionName + " (ThreadID: " +
Thread.CurrentThread.ManagedThreadId.ToString() + ")");
openSim.CreateRegion(regionsToLoad[i], true); openSim.CreateRegion(regionsToLoad[i], true);
} }
} }
} }
public void Close()
{
}
} }
} }

View File

@ -63,4 +63,4 @@ using System.Runtime.InteropServices;
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly : AssemblyVersion("1.0.0.0")] [assembly : AssemblyVersion("1.0.0.0")]
[assembly : AssemblyFileVersion("1.0.0.0")] [assembly : AssemblyFileVersion("1.0.0.0")]

View File

@ -42,9 +42,9 @@ using OpenSim.Framework.Servers;
using OpenSim.Region.ClientStack; using OpenSim.Region.ClientStack;
using OpenSim.Region.Environment.Scenes; using OpenSim.Region.Environment.Scenes;
[assembly:Addin] [assembly : Addin]
[assembly:AddinDependency ("OpenSim", "0.5")] [assembly : AddinDependency("OpenSim", "0.5")]
[assembly:AddinDependency ("RegionProxy", "0.1")] [assembly : AddinDependency("RegionProxy", "0.1")]
namespace OpenSim.ApplicationPlugins.LoadBalancer namespace OpenSim.ApplicationPlugins.LoadBalancer
{ {
@ -53,35 +53,41 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private OpenSimMain simMain;
private BaseHttpServer commandServer; private BaseHttpServer commandServer;
private bool[] isLocalNeighbour;
private List<UDPServer> udpServers; private bool isSplit = false;
private List<RegionInfo> regionData; private TcpServer mTcpServer;
private object padlock = new object();
private int proxyOffset; private int proxyOffset;
private string proxyURL; private string proxyURL;
private List<RegionInfo> regionData;
private int[] regionPortList;
private SceneManager sceneManager; private SceneManager sceneManager;
private string[] sceneURL;
private string serializeDir; private string serializeDir;
private OpenSimMain simMain;
private TcpClient[] tcpClientList;
private List<UDPServer> udpServers;
private TcpServer mTcpServer; #region IApplicationPlugin Members
public void Initialise(OpenSimMain openSim) public void Initialise(OpenSimMain openSim)
{ {
m_log.Info("[BALANCER] "+"Entering Initialize()"); m_log.Info("[BALANCER] " + "Entering Initialize()");
proxyURL = openSim.ConfigSource.Configs["Network"].GetString("proxy_url", ""); proxyURL = openSim.ConfigSource.Configs["Network"].GetString("proxy_url", "");
if(proxyURL.Length==0) return; if (proxyURL.Length == 0) return;
StartTcpServer(); StartTcpServer();
ClientView.SynchronizeClient = new ClientView.SynchronizeClientHandler(SynchronizePackets); ClientView.SynchronizeClient = new ClientView.SynchronizeClientHandler(SynchronizePackets);
AsynchronousSocketListener.PacketHandler = new AsynchronousSocketListener.PacketRecieveHandler(SynchronizePacketRecieve); AsynchronousSocketListener.PacketHandler = new AsynchronousSocketListener.PacketRecieveHandler(SynchronizePacketRecieve);
this.sceneManager = openSim.SceneManager; sceneManager = openSim.SceneManager;
this.udpServers = openSim.UdpServers; udpServers = openSim.UdpServers;
this.regionData = openSim.RegionData; regionData = openSim.RegionData;
this.simMain = openSim; simMain = openSim;
this.commandServer = openSim.HttpServer; commandServer = openSim.HttpServer;
proxyOffset = Int32.Parse(openSim.ConfigSource.Configs["Network"].GetString("proxy_offset", "0")); proxyOffset = Int32.Parse(openSim.ConfigSource.Configs["Network"].GetString("proxy_offset", "0"));
serializeDir = openSim.ConfigSource.Configs["Network"].GetString("serialize_dir", "/tmp/"); serializeDir = openSim.ConfigSource.Configs["Network"].GetString("serialize_dir", "/tmp/");
@ -96,37 +102,40 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
commandServer.AddXmlRPCHandler("UpdatePhysics", UpdatePhysics); commandServer.AddXmlRPCHandler("UpdatePhysics", UpdatePhysics);
commandServer.AddXmlRPCHandler("GetStatus", GetStatus); commandServer.AddXmlRPCHandler("GetStatus", GetStatus);
m_log.Info("[BALANCER] "+"Exiting Initialize()"); m_log.Info("[BALANCER] " + "Exiting Initialize()");
}
private void StartTcpServer()
{
Thread server_thread = new Thread(new ThreadStart(
delegate {
mTcpServer = new TcpServer(10001);
mTcpServer.start();
}));
server_thread.Start();
} }
public void Close() public void Close()
{ {
} }
#endregion
private void StartTcpServer()
{
Thread server_thread = new Thread(new ThreadStart(
delegate
{
mTcpServer = new TcpServer(10001);
mTcpServer.start();
}));
server_thread.Start();
}
private XmlRpcResponse GetStatus(XmlRpcRequest request) private XmlRpcResponse GetStatus(XmlRpcRequest request)
{ {
XmlRpcResponse response = new XmlRpcResponse(); XmlRpcResponse response = new XmlRpcResponse();
try try
{ {
m_log.Info("[BALANCER] "+"Entering RegionStatus()"); m_log.Info("[BALANCER] " + "Entering RegionStatus()");
int src_port = (int)request.Params[0]; int src_port = (int) request.Params[0];
Scene scene = null; Scene scene = null;
// try to get the scene object // try to get the scene object
RegionInfo src_region = SearchRegionFromPortNum(src_port); RegionInfo src_region = SearchRegionFromPortNum(src_port);
if (sceneManager.TryGetScene(src_region.RegionID, out scene) == false) if (sceneManager.TryGetScene(src_region.RegionID, out scene) == false)
{ {
m_log.Error("[BALANCER] "+"The Scene is not found"); m_log.Error("[BALANCER] " + "The Scene is not found");
return response; return response;
} }
// serialization of client's informations // serialization of client's informations
@ -137,7 +146,8 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
{ {
ClientView client = (ClientView) pre.ControllingClient; ClientView client = (ClientView) pre.ControllingClient;
//if(pre.MovementFlag!=0 && client.PacketProcessingEnabled==true) { //if(pre.MovementFlag!=0 && client.PacketProcessingEnabled==true) {
if(client.PacketProcessingEnabled==true) { if (client.PacketProcessingEnabled == true)
{
get_scene_presence_filter++; get_scene_presence_filter++;
} }
} }
@ -149,12 +159,13 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
{ {
ClientView client = (ClientView) pre.ControllingClient; ClientView client = (ClientView) pre.ControllingClient;
//if(pre.MovementFlag!=0 && client.PacketProcessingEnabled==true) { //if(pre.MovementFlag!=0 && client.PacketProcessingEnabled==true) {
if(client.PacketProcessingEnabled==true) { if (client.PacketProcessingEnabled == true)
{
get_avatar_filter++; get_avatar_filter++;
avatar_names += pre.Firstname + " " + pre.Lastname + "; "; avatar_names += pre.Firstname + " " + pre.Lastname + "; ";
} }
} }
Hashtable responseData = new Hashtable(); Hashtable responseData = new Hashtable();
responseData["get_scene_presence_filter"] = get_scene_presence_filter; responseData["get_scene_presence_filter"] = get_scene_presence_filter;
responseData["get_scene_presence"] = get_scene_presence; responseData["get_scene_presence"] = get_scene_presence;
@ -163,12 +174,12 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
responseData["avatar_names"] = avatar_names; responseData["avatar_names"] = avatar_names;
response.Value = responseData; response.Value = responseData;
m_log.Info("[BALANCER] "+"Exiting RegionStatus()"); m_log.Info("[BALANCER] " + "Exiting RegionStatus()");
} }
catch (Exception e) catch (Exception e)
{ {
m_log.Error("[BALANCER] "+e.ToString()); m_log.Error("[BALANCER] " + e.ToString());
m_log.Error("[BALANCER] "+e.StackTrace); m_log.Error("[BALANCER] " + e.StackTrace);
} }
return response; return response;
} }
@ -177,19 +188,19 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
{ {
try try
{ {
m_log.Info("[BALANCER] "+"Entering SerializeRegion()"); m_log.Info("[BALANCER] " + "Entering SerializeRegion()");
string src_url = (string)request.Params[0]; string src_url = (string) request.Params[0];
int src_port = (int)request.Params[1]; int src_port = (int) request.Params[1];
SerializeRegion(src_url, src_port); SerializeRegion(src_url, src_port);
m_log.Info("[BALANCER] "+"Exiting SerializeRegion()"); m_log.Info("[BALANCER] " + "Exiting SerializeRegion()");
} }
catch (Exception e) catch (Exception e)
{ {
m_log.Error("[BALANCER] "+e.ToString()); m_log.Error("[BALANCER] " + e.ToString());
m_log.Error("[BALANCER] "+e.StackTrace); m_log.Error("[BALANCER] " + e.StackTrace);
} }
return new XmlRpcResponse(); return new XmlRpcResponse();
@ -199,21 +210,21 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
{ {
try try
{ {
m_log.Info("[BALANCER] "+"Entering DeserializeRegion_Move()"); m_log.Info("[BALANCER] " + "Entering DeserializeRegion_Move()");
string src_url = (string)request.Params[0]; string src_url = (string) request.Params[0];
int src_port = (int)request.Params[1]; int src_port = (int) request.Params[1];
string dst_url = (string)request.Params[2]; string dst_url = (string) request.Params[2];
int dst_port = (int)request.Params[3]; int dst_port = (int) request.Params[3];
DeserializeRegion_Move(src_port, dst_port, src_url, dst_url); DeserializeRegion_Move(src_port, dst_port, src_url, dst_url);
m_log.Info("[BALANCER] "+"Exiting DeserializeRegion_Move()"); m_log.Info("[BALANCER] " + "Exiting DeserializeRegion_Move()");
} }
catch (Exception e) catch (Exception e)
{ {
m_log.Error("[BALANCER] "+e.ToString()); m_log.Error("[BALANCER] " + e.ToString());
m_log.Error("[BALANCER] "+e.StackTrace); m_log.Error("[BALANCER] " + e.StackTrace);
} }
return new XmlRpcResponse(); return new XmlRpcResponse();
@ -223,21 +234,21 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
{ {
try try
{ {
m_log.Info("[BALANCER] "+"Entering DeserializeRegion_Clone()"); m_log.Info("[BALANCER] " + "Entering DeserializeRegion_Clone()");
string src_url = (string)request.Params[0]; string src_url = (string) request.Params[0];
int src_port = (int)request.Params[1]; int src_port = (int) request.Params[1];
string dst_url = (string)request.Params[2]; string dst_url = (string) request.Params[2];
int dst_port = (int)request.Params[3]; int dst_port = (int) request.Params[3];
DeserializeRegion_Clone(src_port, dst_port, src_url, dst_url); DeserializeRegion_Clone(src_port, dst_port, src_url, dst_url);
m_log.Info("[BALANCER] "+"Exiting DeserializeRegion_Clone()"); m_log.Info("[BALANCER] " + "Exiting DeserializeRegion_Clone()");
} }
catch (Exception e) catch (Exception e)
{ {
m_log.Error("[BALANCER] "+e.ToString()); m_log.Error("[BALANCER] " + e.ToString());
m_log.Error("[BALANCER] "+e.StackTrace); m_log.Error("[BALANCER] " + e.StackTrace);
throw e; throw e;
} }
@ -248,20 +259,20 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
{ {
try try
{ {
m_log.Info("[BALANCER] "+"Entering TerminateRegion()"); m_log.Info("[BALANCER] " + "Entering TerminateRegion()");
int src_port = (int)request.Params[0]; int src_port = (int) request.Params[0];
// backgroud // backgroud
WaitCallback callback = new WaitCallback(TerminateRegion); WaitCallback callback = new WaitCallback(TerminateRegion);
ThreadPool.QueueUserWorkItem(callback, src_port); ThreadPool.QueueUserWorkItem(callback, src_port);
m_log.Info("[BALANCER] "+"Exiting TerminateRegion()"); m_log.Info("[BALANCER] " + "Exiting TerminateRegion()");
} }
catch (Exception e) catch (Exception e)
{ {
m_log.Error("[BALANCER] "+e.ToString()); m_log.Error("[BALANCER] " + e.ToString());
m_log.Error("[BALANCER] "+e.StackTrace); m_log.Error("[BALANCER] " + e.StackTrace);
} }
return new XmlRpcResponse(); return new XmlRpcResponse();
@ -282,7 +293,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
if (src_region == null) if (src_region == null)
{ {
m_log.Error("[BALANCER] "+"Region not found"); m_log.Error("[BALANCER] " + "Region not found");
return; return;
} }
@ -303,8 +314,8 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
// import the source region's data // import the source region's data
dst_region = DeserializeRegion(dst_port, true, serializeDir); dst_region = DeserializeRegion(dst_port, true, serializeDir);
Util.XmlRpcCommand(dst_region.proxyUrl, "ChangeRegion", src_port + proxyOffset, src_url, dst_port + proxyOffset, dst_url); Util.XmlRpcCommand(dst_region.proxyUrl, "ChangeRegion", src_port + proxyOffset, src_url, dst_port + proxyOffset, dst_url);
Util.XmlRpcCommand(dst_region.proxyUrl, "UnblockClientMessages", dst_url, dst_port + proxyOffset); Util.XmlRpcCommand(dst_region.proxyUrl, "UnblockClientMessages", dst_url, dst_port + proxyOffset);
} }
private void DeserializeRegion_Clone(int src_port, int dst_port, string src_url, string dst_url) private void DeserializeRegion_Clone(int src_port, int dst_port, string src_url, string dst_url)
@ -319,19 +330,19 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
dst_region = DeserializeRegion(dst_port, false, serializeDir); dst_region = DeserializeRegion(dst_port, false, serializeDir);
// Decide who is in charge for each section // Decide who is in charge for each section
int[] port = new int[] { src_port, dst_port }; int[] port = new int[] {src_port, dst_port};
string[] url = new string[] { "http://" + src_url + ":" + commandServer.Port, "http://" + dst_url + ":" + commandServer.Port }; string[] url = new string[] {"http://" + src_url + ":" + commandServer.Port, "http://" + dst_url + ":" + commandServer.Port};
for(int i=0; i<2; i++) Util.XmlRpcCommand(url[i], "SplitRegion", i, 2, port[0], port[1], url[0], url[1]); for (int i = 0; i < 2; i++) Util.XmlRpcCommand(url[i], "SplitRegion", i, 2, port[0], port[1], url[0], url[1]);
// Enable the proxy // Enable the proxy
Util.XmlRpcCommand(dst_region.proxyUrl, "AddRegion", src_port + proxyOffset, src_url, dst_port + proxyOffset, dst_url); Util.XmlRpcCommand(dst_region.proxyUrl, "AddRegion", src_port + proxyOffset, src_url, dst_port + proxyOffset, dst_url);
Util.XmlRpcCommand(dst_region.proxyUrl, "UnblockClientMessages", dst_url, dst_port + proxyOffset); Util.XmlRpcCommand(dst_region.proxyUrl, "UnblockClientMessages", dst_url, dst_port + proxyOffset);
} }
private void TerminateRegion(object param) private void TerminateRegion(object param)
{ {
RegionInfo src_region = null; RegionInfo src_region = null;
int src_port = (int)param; int src_port = (int) param;
//------------------------------------------ //------------------------------------------
// Processing of remove region // Processing of remove region
@ -342,7 +353,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
if (src_region == null) if (src_region == null)
{ {
m_log.Error("[BALANCER] "+"Region not found"); m_log.Error("[BALANCER] " + "Region not found");
return; return;
} }
@ -353,7 +364,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
// remove old region // remove old region
RemoveRegion(src_region.RegionID, src_region.InternalEndPoint.Port); RemoveRegion(src_region.RegionID, src_region.InternalEndPoint.Port);
m_log.Info("[BALANCER] "+"Region terminated"); m_log.Info("[BALANCER] " + "Region terminated");
} }
private RegionInfo SearchRegionFromPortNum(int portnum) private RegionInfo SearchRegionFromPortNum(int portnum)
@ -377,7 +388,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
private UDPServer SearchUDPServerFromPortNum(int portnum) private UDPServer SearchUDPServerFromPortNum(int portnum)
{ {
return udpServers.Find( delegate(UDPServer server) { return (portnum + proxyOffset == ((IPEndPoint) server.Server.LocalEndPoint).Port); }); return udpServers.Find(delegate(UDPServer server) { return (portnum + proxyOffset == ((IPEndPoint) server.Server.LocalEndPoint).Port); });
} }
private void SerializeRegion(RegionInfo src_region, string export_dir) private void SerializeRegion(RegionInfo src_region, string export_dir)
@ -390,7 +401,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
// try to get the scene object // try to get the scene object
if (sceneManager.TryGetScene(src_region.RegionID, out scene) == false) if (sceneManager.TryGetScene(src_region.RegionID, out scene) == false)
{ {
m_log.Error("[BALANCER] "+"The Scene is not found"); m_log.Error("[BALANCER] " + "The Scene is not found");
return; return;
} }
@ -419,7 +430,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
// backup current scene's entities // backup current scene's entities
//scene.Backup(); //scene.Backup();
m_log.InfoFormat("[BALANCER] "+"region serialization completed [{0}]", m_log.InfoFormat("[BALANCER] " + "region serialization completed [{0}]",
src_region.RegionID.ToString()); src_region.RegionID.ToString());
} }
@ -428,13 +439,13 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
string filename; string filename;
IClientAPI controller = null; IClientAPI controller = null;
m_log.InfoFormat("[BALANCER] "+"agent id : {0}", pre.UUID); m_log.InfoFormat("[BALANCER] " + "agent id : {0}", pre.UUID);
uint[] circuits = scene.ClientManager.GetAllCircuits(pre.UUID); uint[] circuits = scene.ClientManager.GetAllCircuits(pre.UUID);
foreach (uint code in circuits) foreach (uint code in circuits)
{ {
m_log.InfoFormat("[BALANCER] "+"circuit code : {0}", code); m_log.InfoFormat("[BALANCER] " + "circuit code : {0}", code);
if (scene.ClientManager.TryGetClient(code, out controller)) if (scene.ClientManager.TryGetClient(code, out controller))
{ {
@ -444,7 +455,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
Util.SerializeToFile(filename, info); Util.SerializeToFile(filename, info);
m_log.InfoFormat("[BALANCER] "+"client info serialized [filename={0}]", filename); m_log.InfoFormat("[BALANCER] " + "client info serialized [filename={0}]", filename);
} }
} }
@ -453,7 +464,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
Util.SerializeToFile(filename, pre); Util.SerializeToFile(filename, pre);
m_log.InfoFormat("[BALANCER] "+"scene presence serialized [filename={0}]", filename); m_log.InfoFormat("[BALANCER] " + "scene presence serialized [filename={0}]", filename);
} }
private RegionInfo DeserializeRegion(int dst_port, bool move_flag, string import_dir) private RegionInfo DeserializeRegion(int dst_port, bool move_flag, string import_dir)
@ -470,30 +481,30 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
{ {
m_log.InfoFormat("[BALANCER] RegionInfo filename = [{0}]", filename); m_log.InfoFormat("[BALANCER] RegionInfo filename = [{0}]", filename);
dst_region = new RegionInfo((SearializableRegionInfo)Util.DeserializeFromFile(filename)); dst_region = new RegionInfo((SearializableRegionInfo) Util.DeserializeFromFile(filename));
m_log.InfoFormat("[BALANCER] "+"RegionID = [{0}]", dst_region.RegionID.ToString()); m_log.InfoFormat("[BALANCER] " + "RegionID = [{0}]", dst_region.RegionID.ToString());
m_log.InfoFormat("[BALANCER] "+"RegionHandle = [{0}]", dst_region.RegionHandle); m_log.InfoFormat("[BALANCER] " + "RegionHandle = [{0}]", dst_region.RegionHandle);
m_log.InfoFormat("[BALANCER] "+"ProxyUrl = [{0}]", dst_region.proxyUrl); m_log.InfoFormat("[BALANCER] " + "ProxyUrl = [{0}]", dst_region.proxyUrl);
m_log.InfoFormat("[BALANCER] "+"OriginRegionID = [{0}]", dst_region.originRegionID.ToString()); m_log.InfoFormat("[BALANCER] " + "OriginRegionID = [{0}]", dst_region.originRegionID.ToString());
CreateCloneRegion(dst_region, dst_port, true); CreateCloneRegion(dst_region, dst_port, true);
File.Delete(filename); File.Delete(filename);
m_log.InfoFormat("[BALANCER] "+"region deserialized [{0}]", dst_region.RegionID); m_log.InfoFormat("[BALANCER] " + "region deserialized [{0}]", dst_region.RegionID);
} }
// deserialization of client data // deserialization of client data
DeserializeClient(dst_region, import_dir); DeserializeClient(dst_region, import_dir);
m_log.InfoFormat("[BALANCER] "+"region deserialization completed [{0}]", m_log.InfoFormat("[BALANCER] " + "region deserialization completed [{0}]",
dst_region.ToString()); dst_region.ToString());
} }
catch (Exception e) catch (Exception e)
{ {
m_log.Error("[BALANCER] "+e.ToString()); m_log.Error("[BALANCER] " + e.ToString());
m_log.Error("[BALANCER] "+e.StackTrace); m_log.Error("[BALANCER] " + e.StackTrace);
throw e; throw e;
} }
@ -515,7 +526,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
udpserv = SearchUDPServerFromPortNum(scene.RegionInfo.InternalEndPoint.Port); udpserv = SearchUDPServerFromPortNum(scene.RegionInfo.InternalEndPoint.Port);
// restore the scene presence // restore the scene presence
for (int i = 0; ; i++) for (int i = 0;; i++)
{ {
string filename = import_dir + "Presence_" + String.Format("{0:0000}", i) + ".bin"; string filename = import_dir + "Presence_" + String.Format("{0:0000}", i) + ".bin";
@ -524,7 +535,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
break; break;
} }
sp = (ScenePresence)Util.DeserializeFromFile(filename); sp = (ScenePresence) Util.DeserializeFromFile(filename);
Console.WriteLine("agent id = {0}", sp.UUID); Console.WriteLine("agent id = {0}", sp.UUID);
scene.m_restorePresences.Add(sp.UUID, sp); scene.m_restorePresences.Add(sp.UUID, sp);
@ -543,7 +554,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
uint circuit_code = uint.Parse(fname.Substring(start + 1, end - start - 1)); uint circuit_code = uint.Parse(fname.Substring(start + 1, end - start - 1));
m_log.InfoFormat("[BALANCER] " + "client circuit code = {0}", circuit_code); m_log.InfoFormat("[BALANCER] " + "client circuit code = {0}", circuit_code);
data = (ClientInfo)Util.DeserializeFromFile(fname); data = (ClientInfo) Util.DeserializeFromFile(fname);
AgentCircuitData agentdata = new AgentCircuitData(data.agentcircuit); AgentCircuitData agentdata = new AgentCircuitData(data.agentcircuit);
scene.AuthenticateHandler.AddNewCircuit(circuit_code, agentdata); scene.AuthenticateHandler.AddNewCircuit(circuit_code, agentdata);
@ -582,7 +593,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
// change RegionInfo (memory only) // change RegionInfo (memory only)
dst_region.InternalEndPoint.Port = dst_port; dst_region.InternalEndPoint.Port = dst_port;
dst_region.ExternalHostName = proxyURL.Split(new char[] { '/', ':' })[3]; dst_region.ExternalHostName = proxyURL.Split(new char[] {'/', ':'})[3];
// Create new region // Create new region
simMain.CreateRegion(dst_region, false); simMain.CreateRegion(dst_region, false);
@ -595,7 +606,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
{ {
Console.WriteLine("scene found."); Console.WriteLine("scene found.");
if ((sceneManager.CurrentScene != null) if ((sceneManager.CurrentScene != null)
&& (sceneManager.CurrentScene.RegionInfo.RegionID == killScene.RegionInfo.RegionID)) && (sceneManager.CurrentScene.RegionInfo.RegionID == killScene.RegionInfo.RegionID))
{ {
sceneManager.TrySetCurrentScene(".."); sceneManager.TrySetCurrentScene("..");
@ -614,7 +625,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
udpsvr.Server.Close(); udpsvr.Server.Close();
udpServers.Remove(udpsvr); udpServers.Remove(udpsvr);
} }
} }
private void RemoveAllClientResource(RegionInfo src_region) private void RemoveAllClientResource(RegionInfo src_region)
{ {
@ -625,7 +636,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
// try to get the scene object // try to get the scene object
if (sceneManager.TryGetScene(src_region.RegionID, out scene) == false) if (sceneManager.TryGetScene(src_region.RegionID, out scene) == false)
{ {
m_log.Error("[BALANCER] "+"The Scene is not found"); m_log.Error("[BALANCER] " + "The Scene is not found");
return; return;
} }
@ -639,19 +650,19 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
foreach (uint code in circuits) foreach (uint code in circuits)
{ {
m_log.InfoFormat("[BALANCER] "+"circuit code : {0}", code); m_log.InfoFormat("[BALANCER] " + "circuit code : {0}", code);
if (scene.ClientManager.TryGetClient(code, out controller)) if (scene.ClientManager.TryGetClient(code, out controller))
{ {
// stopping clientview thread // stopping clientview thread
if (((ClientView)controller).PacketProcessingEnabled) if (((ClientView) controller).PacketProcessingEnabled)
{ {
controller.Stop(); controller.Stop();
((ClientView)controller).PacketProcessingEnabled = false; ((ClientView) controller).PacketProcessingEnabled = false;
} }
// teminateing clientview thread // teminateing clientview thread
controller.Terminate(); controller.Terminate();
m_log.Info("[BALANCER] "+"client thread stopped"); m_log.Info("[BALANCER] " + "client thread stopped");
} }
} }
@ -664,12 +675,6 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
* This section implements scene splitting and synchronization * This section implements scene splitting and synchronization
*/ */
private bool[] isLocalNeighbour;
private string[] sceneURL;
private int[] regionPortList;
private TcpClient[] tcpClientList;
private bool isSplit = false;
private XmlRpcResponse SplitRegion(XmlRpcRequest request) private XmlRpcResponse SplitRegion(XmlRpcRequest request)
{ {
try try
@ -680,25 +685,25 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
sceneURL = new string[numRegions]; sceneURL = new string[numRegions];
tcpClientList = new TcpClient[numRegions]; tcpClientList = new TcpClient[numRegions];
for(int i=0; i<numRegions; i++) for (int i = 0; i < numRegions; i++)
{ {
regionPortList[i]=(int) request.Params[i+2]; regionPortList[i] = (int) request.Params[i + 2];
sceneURL[i]=(string) request.Params[i+2+numRegions]; sceneURL[i] = (string) request.Params[i + 2 + numRegions];
} }
string hostname; string hostname;
for(int i=0; i<numRegions; i++) for (int i = 0; i < numRegions; i++)
{ {
hostname = sceneURL[i].Split(new char[] { '/', ':' })[3]; hostname = sceneURL[i].Split(new char[] {'/', ':'})[3];
m_log.InfoFormat("[SPLITSCENE] "+"creating tcp client host:{0}", hostname); m_log.InfoFormat("[SPLITSCENE] " + "creating tcp client host:{0}", hostname);
tcpClientList[i] = new TcpClient(hostname, 10001); tcpClientList[i] = new TcpClient(hostname, 10001);
} }
bool isMaster = (myID == 0); bool isMaster = (myID == 0);
isLocalNeighbour = new bool[numRegions]; isLocalNeighbour = new bool[numRegions];
for(int i=0; i<numRegions; i++) isLocalNeighbour[i] = (sceneURL[i] == sceneURL[myID]); for (int i = 0; i < numRegions; i++) isLocalNeighbour[i] = (sceneURL[i] == sceneURL[myID]);
RegionInfo region = SearchRegionFromPortNum(regionPortList[myID]); RegionInfo region = SearchRegionFromPortNum(regionPortList[myID]);
@ -708,10 +713,11 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
if (sceneManager.TryGetScene(region.RegionID, out scene)) if (sceneManager.TryGetScene(region.RegionID, out scene))
{ {
// Disable event updates, backups etc in the slave(s) // Disable event updates, backups etc in the slave(s)
if (isMaster) { if (isMaster)
{
scene.Region_Status = RegionStatus.Up; scene.Region_Status = RegionStatus.Up;
} }
else else
{ {
scene.Region_Status = RegionStatus.SlaveScene; scene.Region_Status = RegionStatus.SlaveScene;
} }
@ -729,13 +735,13 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
foreach (uint code in circuits) foreach (uint code in circuits)
{ {
m_log.InfoFormat("[BALANCER] "+"circuit code : {0}", code); m_log.InfoFormat("[BALANCER] " + "circuit code : {0}", code);
if (scene.ClientManager.TryGetClient(code, out controller)) if (scene.ClientManager.TryGetClient(code, out controller))
{ {
// Divide the presences evenly over the set of subscenes // Divide the presences evenly over the set of subscenes
ClientView client = (ClientView) controller; ClientView client = (ClientView) controller;
client.PacketProcessingEnabled = (( (i + myID) % sceneURL.Length) == 0); client.PacketProcessingEnabled = (((i + myID) % sceneURL.Length) == 0);
m_log.InfoFormat("[SPLITSCENE] === SplitRegion {0}: SP.PacketEnabled {1}", region.RegionID, client.PacketProcessingEnabled); m_log.InfoFormat("[SPLITSCENE] === SplitRegion {0}: SP.PacketEnabled {1}", region.RegionID, client.PacketProcessingEnabled);
@ -748,20 +754,20 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
++i; ++i;
} }
} }
scene.splitID = myID; scene.splitID = myID;
scene.SynchronizeScene = new Scene.SynchronizeSceneHandler(SynchronizeScenes); scene.SynchronizeScene = new Scene.SynchronizeSceneHandler(SynchronizeScenes);
isSplit = true; isSplit = true;
} }
else else
{ {
m_log.Error("[SPLITSCENE] "+String.Format("Scene not found {0}", region.RegionID)); m_log.Error("[SPLITSCENE] " + String.Format("Scene not found {0}", region.RegionID));
} }
} }
catch (Exception e) catch (Exception e)
{ {
m_log.Error("[SPLITSCENE] "+e.ToString()); m_log.Error("[SPLITSCENE] " + e.ToString());
m_log.Error("[SPLITSCENE] "+e.StackTrace); m_log.Error("[SPLITSCENE] " + e.StackTrace);
} }
return new XmlRpcResponse(); return new XmlRpcResponse();
@ -772,14 +778,14 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
// This should only be called for the master scene // This should only be called for the master scene
try try
{ {
m_log.Info("[BALANCER] "+"Entering MergeRegions()"); m_log.Info("[BALANCER] " + "Entering MergeRegions()");
string src_url = (string) request.Params[0]; string src_url = (string) request.Params[0];
int src_port = (int) request.Params[1]; int src_port = (int) request.Params[1];
RegionInfo region = SearchRegionFromPortNum(src_port); RegionInfo region = SearchRegionFromPortNum(src_port);
Util.XmlRpcCommand(region.proxyUrl, "BlockClientMessages", src_url, src_port + proxyOffset); Util.XmlRpcCommand(region.proxyUrl, "BlockClientMessages", src_url, src_port + proxyOffset);
Scene scene; Scene scene;
if (sceneManager.TryGetScene(region.RegionID, out scene)) if (sceneManager.TryGetScene(region.RegionID, out scene))
@ -802,20 +808,20 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
} }
// Delete the slave scenes // Delete the slave scenes
for(int i=1; i<sceneURL.Length; i++) for (int i = 1; i < sceneURL.Length; i++)
{ {
string url = (sceneURL[i].Split('/')[2]).Split(':')[0]; // get URL part from EP string url = (sceneURL[i].Split('/')[2]).Split(':')[0]; // get URL part from EP
Util.XmlRpcCommand(region.proxyUrl, "DeleteRegion", regionPortList[i] + proxyOffset, url); Util.XmlRpcCommand(region.proxyUrl, "DeleteRegion", regionPortList[i] + proxyOffset, url);
Thread.Sleep(1000); Thread.Sleep(1000);
Util.XmlRpcCommand(sceneURL[i], "TerminateRegion", regionPortList[i]); // TODO: need + proxyOffset? Util.XmlRpcCommand(sceneURL[i], "TerminateRegion", regionPortList[i]); // TODO: need + proxyOffset?
} }
Util.XmlRpcCommand(region.proxyUrl, "UnblockClientMessages", src_url, src_port + proxyOffset); Util.XmlRpcCommand(region.proxyUrl, "UnblockClientMessages", src_url, src_port + proxyOffset);
} }
catch (Exception e) catch (Exception e)
{ {
m_log.Error("[BALANCER] "+e.ToString()); m_log.Error("[BALANCER] " + e.ToString());
m_log.Error("[BALANCER] "+e.StackTrace); m_log.Error("[BALANCER] " + e.StackTrace);
throw e; throw e;
} }
@ -851,7 +857,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
Scene scene; Scene scene;
if (sceneManager.TryGetScene(region.RegionID, out scene)) if (sceneManager.TryGetScene(region.RegionID, out scene))
{ {
ScenePresence pre = scene.GetScenePresences().Find(delegate(ScenePresence x) { return x.UUID == scenePresenceID; }); ScenePresence pre = scene.GetScenePresences().Find(delegate(ScenePresence x) { return x.UUID == scenePresenceID; });
if (pre == null) if (pre == null)
{ {
@ -862,13 +868,12 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
// m_log.Info("[SPLITSCENE] "+"LocalUpdatePhysics [region:{0}, client:{1}]", // m_log.Info("[SPLITSCENE] "+"LocalUpdatePhysics [region:{0}, client:{1}]",
// regionID.ToString(), pre.UUID.ToString()); // regionID.ToString(), pre.UUID.ToString());
pre.AbsolutePosition = position;// will set PhysicsActor.Position pre.AbsolutePosition = position; // will set PhysicsActor.Position
pre.Velocity = velocity; // will set PhysicsActor.Velocity pre.Velocity = velocity; // will set PhysicsActor.Velocity
pre.PhysicsActor.Flying = flying; pre.PhysicsActor.Flying = flying;
} }
} }
object padlock=new object();
private void SynchronizeScenes(Scene scene) private void SynchronizeScenes(Scene scene)
{ {
if (!isSplit) if (!isSplit)
@ -876,7 +881,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
return; return;
} }
lock(padlock) lock (padlock)
{ {
// Callback activated after a physics scene update // Callback activated after a physics scene update
// int i = 0; // int i = 0;
@ -888,7 +893,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
// Because data changes by the physics simulation when the client doesn't move, // Because data changes by the physics simulation when the client doesn't move,
// if MovementFlag is false, It is necessary to synchronize. // if MovementFlag is false, It is necessary to synchronize.
//if(pre.MovementFlag!=0 && client.PacketProcessingEnabled==true) //if(pre.MovementFlag!=0 && client.PacketProcessingEnabled==true)
if(client.PacketProcessingEnabled==true) if (client.PacketProcessingEnabled == true)
{ {
//m_log.Info("[SPLITSCENE] "+String.Format("Client moving in {0} {1}", scene.RegionInfo.RegionID, pre.AbsolutePosition)); //m_log.Info("[SPLITSCENE] "+String.Format("Client moving in {0} {1}", scene.RegionInfo.RegionID, pre.AbsolutePosition));
@ -898,8 +903,8 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
{ {
continue; continue;
} }
if(isLocalNeighbour[i]) if (isLocalNeighbour[i])
{ {
//m_log.Info("[SPLITSCENE] "+"Synchronize ScenePresence (Local) [region:{0}=>{1}, client:{2}]", //m_log.Info("[SPLITSCENE] "+"Synchronize ScenePresence (Local) [region:{0}=>{1}, client:{2}]",
// scene.RegionInfo.RegionID, regionPortList[i], pre.UUID.ToString()); // scene.RegionInfo.RegionID, regionPortList[i], pre.UUID.ToString());
@ -912,7 +917,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
// pre.Velocity.ToString(), pre.PhysicsActor.Flying); // pre.Velocity.ToString(), pre.PhysicsActor.Flying);
Util.XmlRpcCommand(sceneURL[i], "UpdatePhysics", Util.XmlRpcCommand(sceneURL[i], "UpdatePhysics",
regionPortList[i], pre.UUID.GetBytes(), regionPortList[i], pre.UUID.GetBytes(),
pre.AbsolutePosition.GetBytes(), pre.Velocity.GetBytes(), pre.AbsolutePosition.GetBytes(), pre.Velocity.GetBytes(),
pre.PhysicsActor.Flying); pre.PhysicsActor.Flying);
@ -951,7 +956,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
return false; return false;
} }
Scene localScene = (Scene)scene; Scene localScene = (Scene) scene;
for (int i = 0; i < sceneURL.Length; i++) for (int i = 0; i < sceneURL.Length; i++)
{ {
@ -959,8 +964,8 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
{ {
continue; continue;
} }
if(isLocalNeighbour[i]) if (isLocalNeighbour[i])
{ {
//m_log.Info("[SPLITSCENE] "+"Synchronize Packet (Local) [type:{0}, client:{1}]", //m_log.Info("[SPLITSCENE] "+"Synchronize Packet (Local) [type:{0}, client:{1}]",
// packet.Type.ToString(), agentID.ToString()); // packet.Type.ToString(), agentID.ToString());
@ -977,7 +982,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
InternalPacketHeader header = new InternalPacketHeader(); InternalPacketHeader header = new InternalPacketHeader();
header.type = 0; header.type = 0;
header.throttlePacketType = (int)throttlePacketType; header.throttlePacketType = (int) throttlePacketType;
header.numbytes = buff.Length; header.numbytes = buff.Length;
header.agent_id = agentID.UUID; header.agent_id = agentID.UUID;
header.region_port = regionPortList[i]; header.region_port = regionPortList[i];
@ -1003,7 +1008,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
if (sceneManager.TryGetScene(region.RegionID, out scene)) if (sceneManager.TryGetScene(region.RegionID, out scene))
{ {
ScenePresence pre = scene.GetScenePresences().Find(delegate(ScenePresence x) { return x.UUID == agentID; }); ScenePresence pre = scene.GetScenePresences().Find(delegate(ScenePresence x) { return x.UUID == agentID; });
if (pre == null) if (pre == null)
{ {
@ -1011,7 +1016,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
return; return;
} }
if (((ClientView)pre.ControllingClient).PacketProcessingEnabled==true) if (((ClientView) pre.ControllingClient).PacketProcessingEnabled == true)
{ {
pre.ControllingClient.OutPacket(packet, throttlePacketType); pre.ControllingClient.OutPacket(packet, throttlePacketType);
} }
@ -1050,13 +1055,13 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
packet = PacketPool.Instance.GetPacket(buff, ref packetEnd, zero); packet = PacketPool.Instance.GetPacket(buff, ref packetEnd, zero);
LocalUpdatePacket(header.region_port, new LLUUID(header.agent_id), LocalUpdatePacket(header.region_port, new LLUUID(header.agent_id),
packet, (ThrottleOutPacketType)header.throttlePacketType); packet, (ThrottleOutPacketType) header.throttlePacketType);
} }
catch (Exception e) catch (Exception e)
{ {
m_log.Error("[SPLITSCENE] "+e.ToString()); m_log.Error("[SPLITSCENE] " + e.ToString());
m_log.Error("[SPLITSCENE] "+e.StackTrace); m_log.Error("[SPLITSCENE] " + e.StackTrace);
} }
break; break;
@ -1067,18 +1072,18 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer
LLUUID scenePresenceID = new LLUUID(header.agent_id); LLUUID scenePresenceID = new LLUUID(header.agent_id);
LLVector3 position = new LLVector3(buff, 0); LLVector3 position = new LLVector3(buff, 0);
LLVector3 velocity = new LLVector3(buff, 12); LLVector3 velocity = new LLVector3(buff, 12);
bool flying = ((buff[24] == (byte)1)?true:false); bool flying = ((buff[24] == (byte) 1) ? true : false);
LocalUpdatePhysics(regionPort, scenePresenceID, position, velocity, flying); LocalUpdatePhysics(regionPort, scenePresenceID, position, velocity, flying);
break; break;
default: default:
m_log.Info("[SPLITSCENE] "+"Invalid type"); m_log.Info("[SPLITSCENE] " + "Invalid type");
break; break;
} }
// m_log.Info("[SPLITSCENE] "+"exiting SynchronizePacketRecieve"); // m_log.Info("[SPLITSCENE] "+"exiting SynchronizePacketRecieve");
} }
} }
} }

View File

@ -30,19 +30,23 @@ using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Threading; using System.Threading;
namespace OpenSim.ApplicationPlugins.LoadBalancer { namespace OpenSim.ApplicationPlugins.LoadBalancer
public class AsynchronousClient { {
public class AsynchronousClient
{
private static ManualResetEvent connectDone = new ManualResetEvent(false); private static ManualResetEvent connectDone = new ManualResetEvent(false);
private static ManualResetEvent sendDone = new ManualResetEvent(false); private static ManualResetEvent sendDone = new ManualResetEvent(false);
public static Socket StartClient(string hostname, int port) { public static Socket StartClient(string hostname, int port)
try { {
try
{
IPHostEntry ipHostInfo = Dns.GetHostEntry(hostname); IPHostEntry ipHostInfo = Dns.GetHostEntry(hostname);
IPAddress ipAddress = ipHostInfo.AddressList[0]; IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint remoteEP = new IPEndPoint(ipAddress, port); IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
client.BeginConnect( remoteEP, new AsyncCallback(ConnectCallback), client); client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);
connectDone.WaitOne(); connectDone.WaitOne();
/* /*
Send(client,"This is a test<EOF>"); Send(client,"This is a test<EOF>");
@ -53,19 +57,25 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer {
client.Close(); client.Close();
*/ */
return client; return client;
} catch (Exception e) { }
catch (Exception e)
{
Console.WriteLine(e.ToString()); Console.WriteLine(e.ToString());
throw new Exception("socket error !!"); throw new Exception("socket error !!");
} }
} }
private static void ConnectCallback(IAsyncResult ar) { private static void ConnectCallback(IAsyncResult ar)
try { {
try
{
Socket client = (Socket) ar.AsyncState; Socket client = (Socket) ar.AsyncState;
client.EndConnect(ar); client.EndConnect(ar);
Console.WriteLine("Socket connected to {0}", client.RemoteEndPoint.ToString()); Console.WriteLine("Socket connected to {0}", client.RemoteEndPoint.ToString());
connectDone.Set(); connectDone.Set();
} catch (Exception e) { }
catch (Exception e)
{
Console.WriteLine(e.ToString()); Console.WriteLine(e.ToString());
} }
} }
@ -101,20 +111,26 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer {
} }
} }
*/ */
public static void Send(Socket client, byte[] byteData) {
public static void Send(Socket client, byte[] byteData)
{
client.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), client); client.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), client);
} }
private static void SendCallback(IAsyncResult ar) { private static void SendCallback(IAsyncResult ar)
try { {
try
{
Socket client = (Socket) ar.AsyncState; Socket client = (Socket) ar.AsyncState;
int bytesSent = client.EndSend(ar); int bytesSent = client.EndSend(ar);
if(bytesSent > 0) if (bytesSent > 0)
{ {
//Console.WriteLine("Sent {0} bytes to server.", bytesSent); //Console.WriteLine("Sent {0} bytes to server.", bytesSent);
} }
sendDone.Set(); sendDone.Set();
} catch (Exception e) { }
catch (Exception e)
{
Console.WriteLine(e.ToString()); Console.WriteLine(e.ToString());
} }
} }
@ -122,28 +138,28 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer {
public class InternalPacketHeader public class InternalPacketHeader
{ {
private byte[] buffer = new byte[32];
public int type;
public int throttlePacketType;
public int numbytes;
public Guid agent_id; public Guid agent_id;
private byte[] buffer = new byte[32];
public int numbytes;
public int region_port; public int region_port;
public int throttlePacketType;
public int type;
public void FromBytes(byte[] bytes) public void FromBytes(byte[] bytes)
{ {
int i = 0; // offset int i = 0; // offset
try try
{ {
this.type = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24)); type = (int) (bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
this.throttlePacketType = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24)); throttlePacketType = (int) (bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
this.numbytes = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24)); numbytes = (int) (bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
this.agent_id = new Guid( agent_id = new Guid(
bytes[i++] | (bytes[i++] << 8) | (bytes[i++] << 16) | bytes[i++] << 24, bytes[i++] | (bytes[i++] << 8) | (bytes[i++] << 16) | bytes[i++] << 24,
(short)(bytes[i++] | (bytes[i++] << 8)), (short) (bytes[i++] | (bytes[i++] << 8)),
(short)(bytes[i++] | (bytes[i++] << 8)), (short) (bytes[i++] | (bytes[i++] << 8)),
bytes[i++], bytes[i++], bytes[i++], bytes[i++], bytes[i++], bytes[i++], bytes[i++], bytes[i++],
bytes[i++], bytes[i++], bytes[i++], bytes[i++]); bytes[i++], bytes[i++], bytes[i++], bytes[i++]);
this.region_port = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24)); region_port = (int) (bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
} }
catch (Exception) catch (Exception)
{ {
@ -154,48 +170,54 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer {
public byte[] ToBytes() public byte[] ToBytes()
{ {
int i = 0; int i = 0;
this.buffer[i++] = (byte)(this.type % 256); buffer[i++] = (byte) (type % 256);
this.buffer[i++] = (byte)((this.type >> 8) % 256); buffer[i++] = (byte) ((type >> 8) % 256);
this.buffer[i++] = (byte)((this.type >> 16) % 256); buffer[i++] = (byte) ((type >> 16) % 256);
this.buffer[i++] = (byte)((this.type >> 24) % 256); buffer[i++] = (byte) ((type >> 24) % 256);
this.buffer[i++] = (byte)(this.throttlePacketType % 256); buffer[i++] = (byte) (throttlePacketType % 256);
this.buffer[i++] = (byte)((this.throttlePacketType >> 8) % 256); buffer[i++] = (byte) ((throttlePacketType >> 8) % 256);
this.buffer[i++] = (byte)((this.throttlePacketType >> 16) % 256); buffer[i++] = (byte) ((throttlePacketType >> 16) % 256);
this.buffer[i++] = (byte)((this.throttlePacketType >> 24) % 256); buffer[i++] = (byte) ((throttlePacketType >> 24) % 256);
this.buffer[i++] = (byte)(this.numbytes % 256); buffer[i++] = (byte) (numbytes % 256);
this.buffer[i++] = (byte)((this.numbytes >> 8) % 256); buffer[i++] = (byte) ((numbytes >> 8) % 256);
this.buffer[i++] = (byte)((this.numbytes >> 16) % 256); buffer[i++] = (byte) ((numbytes >> 16) % 256);
this.buffer[i++] = (byte)((this.numbytes >> 24) % 256); buffer[i++] = (byte) ((numbytes >> 24) % 256);
// no endian care // no endian care
Buffer.BlockCopy(agent_id.ToByteArray(), 0, this.buffer, i, 16); i += 16; Buffer.BlockCopy(agent_id.ToByteArray(), 0, buffer, i, 16);
i += 16;
this.buffer[i++] = (byte)(this.region_port % 256); buffer[i++] = (byte) (region_port % 256);
this.buffer[i++] = (byte)((this.region_port >> 8) % 256); buffer[i++] = (byte) ((region_port >> 8) % 256);
this.buffer[i++] = (byte)((this.region_port >> 16) % 256); buffer[i++] = (byte) ((region_port >> 16) % 256);
this.buffer[i++] = (byte)((this.region_port >> 24) % 256); buffer[i++] = (byte) ((region_port >> 24) % 256);
return this.buffer; return buffer;
} }
} }
public class TcpClient { public class TcpClient
{
public static int internalPacketHeaderSize = 4*4 + 16*1; public static int internalPacketHeaderSize = 4 * 4 + 16 * 1;
private Socket mConnection;
private string mHostname; private string mHostname;
private int mPort; private int mPort;
private Socket mConnection;
public TcpClient(string hostname, int port) { public TcpClient(string hostname, int port)
this.mHostname = hostname; {
this.mPort = port; mHostname = hostname;
this.mConnection = null; mPort = port;
mConnection = null;
} }
public void connect() {
this.mConnection = AsynchronousClient.StartClient(mHostname, mPort); public void connect()
{
mConnection = AsynchronousClient.StartClient(mHostname, mPort);
} }
/* /*
public void recevie() { public void recevie() {
if (mConnection == null) { if (mConnection == null) {
@ -212,17 +234,18 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer {
} }
} }
*/ */
public void send(InternalPacketHeader header, byte[] packet) {
public void send(InternalPacketHeader header, byte[] packet)
{
lock (this) lock (this)
{ {
if (mConnection == null)
if (mConnection == null) { {
// throw new Exception("client not initialized"); // throw new Exception("client not initialized");
connect(); connect();
} }
AsynchronousClient.Send(this.mConnection, header.ToBytes()); AsynchronousClient.Send(mConnection, header.ToBytes());
/* /*
for (int i = 0; i < 10; i++) for (int i = 0; i < 10; i++)
@ -231,8 +254,8 @@ for (int i = 0; i < 10; i++)
} }
Console.WriteLine(""); Console.WriteLine("");
*/ */
AsynchronousClient.Send(this.mConnection, packet); AsynchronousClient.Send(mConnection, packet);
} }
} }
} }
} }

View File

@ -31,42 +31,58 @@ using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Threading; using System.Threading;
namespace OpenSim.ApplicationPlugins.LoadBalancer { namespace OpenSim.ApplicationPlugins.LoadBalancer
{
public class StateObject { public class StateObject
public Socket workSocket = null; {
public const int BufferSize = 2048; public const int BufferSize = 2048;
public byte[] buffer = new byte[BufferSize]; public byte[] buffer = new byte[BufferSize];
public MemoryStream ms_ptr = new MemoryStream();
public InternalPacketHeader header = null; public InternalPacketHeader header = null;
public MemoryStream ms_ptr = new MemoryStream();
public Socket workSocket = null;
} }
public class AsynchronousSocketListener { public class AsynchronousSocketListener
public static string data = null; {
public static ManualResetEvent allDone = new ManualResetEvent(false); public static ManualResetEvent allDone = new ManualResetEvent(false);
public static string data = null;
#region KIRYU
#region Delegates
#region KIRYU
public delegate void PacketRecieveHandler(InternalPacketHeader header, byte[] buff); public delegate void PacketRecieveHandler(InternalPacketHeader header, byte[] buff);
#endregion
public static PacketRecieveHandler PacketHandler = null; public static PacketRecieveHandler PacketHandler = null;
#endregion
public AsynchronousSocketListener() { } #endregion
public static void StartListening(int port) { public AsynchronousSocketListener()
{
}
public static void StartListening(int port)
{
IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName()); IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0]; IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, port); IPEndPoint localEndPoint = new IPEndPoint(ipAddress, port);
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp ); Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try { try
{
listener.Bind(localEndPoint); listener.Bind(localEndPoint);
listener.Listen(100); listener.Listen(100);
while (true) { while (true)
{
allDone.Reset(); allDone.Reset();
listener.BeginAccept( new AsyncCallback(AcceptCallback), listener ); listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
allDone.WaitOne(); allDone.WaitOne();
} }
} catch (Exception e) { }
catch (Exception e)
{
Console.WriteLine(e.ToString()); Console.WriteLine(e.ToString());
} }
/* /*
@ -75,38 +91,41 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer {
*/ */
} }
public static void AcceptCallback(IAsyncResult ar) { public static void AcceptCallback(IAsyncResult ar)
{
allDone.Set(); allDone.Set();
Socket listener = (Socket) ar.AsyncState; Socket listener = (Socket) ar.AsyncState;
Socket handler = listener.EndAccept(ar); Socket handler = listener.EndAccept(ar);
StateObject state = new StateObject(); StateObject state = new StateObject();
state.workSocket = handler; state.workSocket = handler;
handler.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
} }
public static void ReadCallback(IAsyncResult ar) { public static void ReadCallback(IAsyncResult ar)
{
StateObject state = (StateObject) ar.AsyncState; StateObject state = (StateObject) ar.AsyncState;
Socket handler = state.workSocket; Socket handler = state.workSocket;
try try
{ {
int bytesRead = handler.EndReceive(ar); int bytesRead = handler.EndReceive(ar);
//MainLog.Instance.Verbose("TCPSERVER", "Received packet [{0}]", bytesRead); //MainLog.Instance.Verbose("TCPSERVER", "Received packet [{0}]", bytesRead);
if (bytesRead > 0) { if (bytesRead > 0)
{
state.ms_ptr.Write(state.buffer, 0, bytesRead); state.ms_ptr.Write(state.buffer, 0, bytesRead);
} }
else else
{ {
//MainLog.Instance.Verbose("TCPSERVER", "Connection terminated"); //MainLog.Instance.Verbose("TCPSERVER", "Connection terminated");
return; return;
} }
long rest_size = state.ms_ptr.Length; long rest_size = state.ms_ptr.Length;
long current_pos = 0; long current_pos = 0;
while (rest_size > TcpClient.internalPacketHeaderSize) { while (rest_size > TcpClient.internalPacketHeaderSize)
{
if ((state.header == null) && (rest_size >= TcpClient.internalPacketHeaderSize)) if ((state.header == null) && (rest_size >= TcpClient.internalPacketHeaderSize))
{ {
//MainLog.Instance.Verbose("TCPSERVER", "Processing header"); //MainLog.Instance.Verbose("TCPSERVER", "Processing header");
@ -136,7 +155,7 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer {
} }
System.Console.WriteLine(); System.Console.WriteLine();
*/ */
state.ms_ptr.Seek(0, SeekOrigin.End); state.ms_ptr.Seek(0, SeekOrigin.End);
// call loadbarancer function // call loadbarancer function
if (PacketHandler != null) if (PacketHandler != null)
@ -155,20 +174,18 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer {
rest_size -= read_size; rest_size -= read_size;
current_pos += read_size; current_pos += read_size;
if (rest_size < TcpClient.internalPacketHeaderSize) { if (rest_size < TcpClient.internalPacketHeaderSize)
{
byte[] rest_bytes = new byte[rest_size]; byte[] rest_bytes = new byte[rest_size];
state.ms_ptr.Position = read_size; state.ms_ptr.Position = read_size;
state.ms_ptr.Read(rest_bytes, 0, (int)rest_size); state.ms_ptr.Read(rest_bytes, 0, (int) rest_size);
state.ms_ptr.Close(); state.ms_ptr.Close();
state.ms_ptr = new MemoryStream(); state.ms_ptr = new MemoryStream();
state.ms_ptr.Write(rest_bytes, 0, (int)rest_size); state.ms_ptr.Write(rest_bytes, 0, (int) rest_size);
break; break;
} }
} }
} // while (true) } // while (true)
} }
catch (Exception) catch (Exception)
{ {
@ -176,19 +193,26 @@ namespace OpenSim.ApplicationPlugins.LoadBalancer {
//MainLog.Instance.Verbose("TCPSERVER", e.StackTrace); //MainLog.Instance.Verbose("TCPSERVER", e.StackTrace);
} }
handler.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
} }
} }
public class TcpServer { public class TcpServer
{
private int mPort = 11000; private int mPort = 11000;
public TcpServer() {
public TcpServer()
{
} }
public TcpServer(int port) {
public TcpServer(int port)
{
mPort = port; mPort = port;
} }
public void start() {
public void start()
{
AsynchronousSocketListener.StartListening(mPort); AsynchronousSocketListener.StartListening(mPort);
} }
} }
} }

View File

@ -37,8 +37,8 @@ using Nwc.XmlRpc;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Servers; using OpenSim.Framework.Servers;
[assembly:Addin ("RegionProxy", "0.1")] [assembly : Addin("RegionProxy", "0.1")]
[assembly:AddinDependency ("OpenSim", "0.5")] [assembly : AddinDependency("OpenSim", "0.5")]
namespace OpenSim.ApplicationPlugins.RegionProxy namespace OpenSim.ApplicationPlugins.RegionProxy
{ {
@ -63,17 +63,19 @@ namespace OpenSim.ApplicationPlugins.RegionProxy
[Extension("/OpenSim/Startup")] [Extension("/OpenSim/Startup")]
public class RegionProxyPlugin : IApplicationPlugin public class RegionProxyPlugin : IApplicationPlugin
{ {
private ProxyServer proxy;
private BaseHttpServer command_server;
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private BaseHttpServer command_server;
private ProxyServer proxy;
#region IApplicationPlugin Members
public void Initialise(OpenSimMain openSim) public void Initialise(OpenSimMain openSim)
{ {
Console.WriteLine("Starting proxy"); Console.WriteLine("Starting proxy");
string proxyURL = openSim.ConfigSource.Configs["Network"].GetString("proxy_url", ""); string proxyURL = openSim.ConfigSource.Configs["Network"].GetString("proxy_url", "");
if(proxyURL.Length==0) return; if (proxyURL.Length == 0) return;
uint port = (uint) Int32.Parse(proxyURL.Split(new char[] { ':' })[2]); uint port = (uint) Int32.Parse(proxyURL.Split(new char[] {':'})[2]);
command_server = new BaseHttpServer(port); command_server = new BaseHttpServer(port);
command_server.Start(); command_server.Start();
command_server.AddXmlRPCHandler("AddPort", AddPort); command_server.AddXmlRPCHandler("AddPort", AddPort);
@ -84,13 +86,15 @@ namespace OpenSim.ApplicationPlugins.RegionProxy
command_server.AddXmlRPCHandler("UnblockClientMessages", UnblockClientMessages); command_server.AddXmlRPCHandler("UnblockClientMessages", UnblockClientMessages);
command_server.AddXmlRPCHandler("Stop", Stop); command_server.AddXmlRPCHandler("Stop", Stop);
proxy=new ProxyServer(m_log); proxy = new ProxyServer(m_log);
} }
public void Close() public void Close()
{ {
} }
#endregion
private XmlRpcResponse Stop(XmlRpcRequest request) private XmlRpcResponse Stop(XmlRpcRequest request)
{ {
try try
@ -107,176 +111,118 @@ namespace OpenSim.ApplicationPlugins.RegionProxy
private XmlRpcResponse AddPort(XmlRpcRequest request) private XmlRpcResponse AddPort(XmlRpcRequest request)
{ {
try { try
{
int clientPort = (int) request.Params[0]; int clientPort = (int) request.Params[0];
int regionPort = (int) request.Params[1]; int regionPort = (int) request.Params[1];
string regionUrl = (string) request.Params[2]; string regionUrl = (string) request.Params[2];
proxy.AddPort(clientPort, regionPort, regionUrl); proxy.AddPort(clientPort, regionPort, regionUrl);
} catch(Exception e) { }
m_log.Error("[PROXY]"+e.Message); catch (Exception e)
m_log.Error("[PROXY]"+e.StackTrace); {
m_log.Error("[PROXY]" + e.Message);
m_log.Error("[PROXY]" + e.StackTrace);
} }
return new XmlRpcResponse(); return new XmlRpcResponse();
} }
private XmlRpcResponse AddRegion(XmlRpcRequest request) private XmlRpcResponse AddRegion(XmlRpcRequest request)
{ {
try { try
{
int currentRegionPort = (int) request.Params[0]; int currentRegionPort = (int) request.Params[0];
string currentRegionUrl = (string) request.Params[1]; string currentRegionUrl = (string) request.Params[1];
int newRegionPort = (int) request.Params[2]; int newRegionPort = (int) request.Params[2];
string newRegionUrl = (string) request.Params[3]; string newRegionUrl = (string) request.Params[3];
proxy.AddRegion(currentRegionPort, currentRegionUrl, newRegionPort, newRegionUrl); proxy.AddRegion(currentRegionPort, currentRegionUrl, newRegionPort, newRegionUrl);
} catch(Exception e) { }
m_log.Error("[PROXY]"+e.Message); catch (Exception e)
m_log.Error("[PROXY]"+e.StackTrace); {
m_log.Error("[PROXY]" + e.Message);
m_log.Error("[PROXY]" + e.StackTrace);
} }
return new XmlRpcResponse(); return new XmlRpcResponse();
} }
private XmlRpcResponse ChangeRegion(XmlRpcRequest request) private XmlRpcResponse ChangeRegion(XmlRpcRequest request)
{ {
try { try
{
int currentRegionPort = (int) request.Params[0]; int currentRegionPort = (int) request.Params[0];
string currentRegionUrl = (string) request.Params[1]; string currentRegionUrl = (string) request.Params[1];
int newRegionPort = (int) request.Params[2]; int newRegionPort = (int) request.Params[2];
string newRegionUrl = (string) request.Params[3]; string newRegionUrl = (string) request.Params[3];
proxy.ChangeRegion(currentRegionPort, currentRegionUrl, newRegionPort, newRegionUrl); proxy.ChangeRegion(currentRegionPort, currentRegionUrl, newRegionPort, newRegionUrl);
} catch(Exception e) { }
m_log.Error("[PROXY]"+e.Message); catch (Exception e)
m_log.Error("[PROXY]"+e.StackTrace); {
m_log.Error("[PROXY]" + e.Message);
m_log.Error("[PROXY]" + e.StackTrace);
} }
return new XmlRpcResponse(); return new XmlRpcResponse();
} }
private XmlRpcResponse DeleteRegion(XmlRpcRequest request) private XmlRpcResponse DeleteRegion(XmlRpcRequest request)
{ {
try { try
{
int currentRegionPort = (int) request.Params[0]; int currentRegionPort = (int) request.Params[0];
string currentRegionUrl = (string) request.Params[1]; string currentRegionUrl = (string) request.Params[1];
proxy.DeleteRegion(currentRegionPort, currentRegionUrl); proxy.DeleteRegion(currentRegionPort, currentRegionUrl);
} catch(Exception e) { }
m_log.Error("[PROXY]"+e.Message); catch (Exception e)
m_log.Error("[PROXY]"+e.StackTrace); {
m_log.Error("[PROXY]" + e.Message);
m_log.Error("[PROXY]" + e.StackTrace);
} }
return new XmlRpcResponse(); return new XmlRpcResponse();
} }
private XmlRpcResponse BlockClientMessages(XmlRpcRequest request) private XmlRpcResponse BlockClientMessages(XmlRpcRequest request)
{ {
try { try
{
string regionUrl = (string) request.Params[0]; string regionUrl = (string) request.Params[0];
int regionPort = (int) request.Params[1]; int regionPort = (int) request.Params[1];
proxy.BlockClientMessages(regionUrl, regionPort); proxy.BlockClientMessages(regionUrl, regionPort);
} catch(Exception e) { }
m_log.Error("[PROXY]"+e.Message); catch (Exception e)
m_log.Error("[PROXY]"+e.StackTrace); {
m_log.Error("[PROXY]" + e.Message);
m_log.Error("[PROXY]" + e.StackTrace);
} }
return new XmlRpcResponse(); return new XmlRpcResponse();
} }
private XmlRpcResponse UnblockClientMessages(XmlRpcRequest request) private XmlRpcResponse UnblockClientMessages(XmlRpcRequest request)
{ {
try { try
{
string regionUrl = (string) request.Params[0]; string regionUrl = (string) request.Params[0];
int regionPort = (int) request.Params[1]; int regionPort = (int) request.Params[1];
proxy.UnblockClientMessages(regionUrl, regionPort); proxy.UnblockClientMessages(regionUrl, regionPort);
} catch(Exception e) { }
m_log.Error("[PROXY]"+e.Message); catch (Exception e)
m_log.Error("[PROXY]"+e.StackTrace); {
m_log.Error("[PROXY]" + e.Message);
m_log.Error("[PROXY]" + e.StackTrace);
} }
return new XmlRpcResponse(); return new XmlRpcResponse();
} }
} }
public class ProxyServer { public class ProxyServer
protected AsyncCallback receivedData; {
protected ProxyMap proxy_map = new ProxyMap();
protected readonly ILog m_log; protected readonly ILog m_log;
protected ProxyMap proxy_map = new ProxyMap();
protected AsyncCallback receivedData;
protected bool running; protected bool running;
protected class ProxyMap
{
public class RegionData
{
public bool isBlocked = false;
public Queue storedMessages = new Queue();
public List<EndPoint> regions = new List<EndPoint>();
}
private Dictionary<EndPoint, RegionData> map;
public ProxyMap() {
map = new Dictionary<EndPoint, RegionData>();
}
public void Add(EndPoint client, EndPoint region)
{
if(map.ContainsKey(client))
{
map[client].regions.Add(region);
}
else
{
RegionData regions = new RegionData();
map.Add(client, regions);
regions.regions.Add(region);
}
}
public RegionData GetRegionData(EndPoint client)
{
return map[client];
}
public EndPoint GetClient(EndPoint region)
{
foreach (KeyValuePair<EndPoint, RegionData> pair in map)
{
if(pair.Value.regions.Contains(region))
{
return pair.Key;
}
}
return null;
}
}
protected class ServerData {
public Socket server;
public EndPoint clientEP;
public EndPoint senderEP;
public IPEndPoint serverIP;
public byte[] recvBuffer = new byte[4096];
public ServerData()
{
server = null;
}
}
protected class StoredMessage
{
public byte[] buffer;
public int length;
public EndPoint senderEP;
public ServerData sd;
public StoredMessage(byte[] buffer, int length, int maxLength, EndPoint senderEP, ServerData sd)
{
this.buffer = new byte[maxLength];
this.length = length;
for(int i=0; i<length; i++) this.buffer[i]=buffer[i];
this.senderEP = senderEP;
this.sd = sd;
}
}
public ProxyServer(ILog log) public ProxyServer(ILog log)
{ {
m_log = log; m_log = log;
running=false; running = false;
receivedData = new AsyncCallback(OnReceivedData); receivedData = new AsyncCallback(OnReceivedData);
} }
@ -293,7 +239,8 @@ namespace OpenSim.ApplicationPlugins.RegionProxy
ProxyMap.RegionData rd = proxy_map.GetRegionData(client); ProxyMap.RegionData rd = proxy_map.GetRegionData(client);
rd.isBlocked = false; rd.isBlocked = false;
while(rd.storedMessages.Count > 0) { while (rd.storedMessages.Count > 0)
{
StoredMessage msg = (StoredMessage) rd.storedMessages.Dequeue(); StoredMessage msg = (StoredMessage) rd.storedMessages.Dequeue();
//m_log.Verbose("[PROXY]"+"Resending blocked message from {0}", msg.senderEP); //m_log.Verbose("[PROXY]"+"Resending blocked message from {0}", msg.senderEP);
SendMessage(msg.buffer, msg.length, msg.senderEP, msg.sd); SendMessage(msg.buffer, msg.length, msg.senderEP, msg.sd);
@ -316,10 +263,10 @@ namespace OpenSim.ApplicationPlugins.RegionProxy
data.regions.Clear(); data.regions.Clear();
data.regions.Add(new IPEndPoint(IPAddress.Parse(newRegionUrl), newRegionPort)); data.regions.Add(new IPEndPoint(IPAddress.Parse(newRegionUrl), newRegionPort));
} }
public void DeleteRegion(int oldRegionPort, string oldRegionUrl) public void DeleteRegion(int oldRegionPort, string oldRegionUrl)
{ {
m_log.InfoFormat("[PROXY]"+"DeleteRegion {0} {1}", oldRegionPort, oldRegionUrl); m_log.InfoFormat("[PROXY]" + "DeleteRegion {0} {1}", oldRegionPort, oldRegionUrl);
EndPoint regionEP = new IPEndPoint(IPAddress.Parse(oldRegionUrl), oldRegionPort); EndPoint regionEP = new IPEndPoint(IPAddress.Parse(oldRegionUrl), oldRegionPort);
EndPoint client = proxy_map.GetClient(regionEP); EndPoint client = proxy_map.GetClient(regionEP);
ProxyMap.RegionData data = proxy_map.GetRegionData(client); ProxyMap.RegionData data = proxy_map.GetRegionData(client);
@ -348,9 +295,8 @@ namespace OpenSim.ApplicationPlugins.RegionProxy
try try
{ {
m_log.InfoFormat("[PROXY] Opening UDP socket on {0}", sd.clientEP); m_log.InfoFormat("[PROXY] Opening UDP socket on {0}", sd.clientEP);
sd.serverIP = new IPEndPoint(IPAddress.Parse("0.0.0.0"), ((IPEndPoint)sd.clientEP).Port); sd.serverIP = new IPEndPoint(IPAddress.Parse("0.0.0.0"), ((IPEndPoint) sd.clientEP).Port);
sd.server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); sd.server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
sd.server.Bind(sd.serverIP); sd.server.Bind(sd.serverIP);
@ -385,15 +331,14 @@ namespace OpenSim.ApplicationPlugins.RegionProxy
{ {
running = false; running = false;
m_log.InfoFormat("[PROXY] Stopping the proxy server"); m_log.InfoFormat("[PROXY] Stopping the proxy server");
} }
protected virtual void OnReceivedData(IAsyncResult result) protected virtual void OnReceivedData(IAsyncResult result)
{ {
if(!running) return; if (!running) return;
ServerData sd = (ServerData)result.AsyncState; ServerData sd = (ServerData) result.AsyncState;
sd.senderEP = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0); sd.senderEP = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0);
try try
@ -431,7 +376,7 @@ namespace OpenSim.ApplicationPlugins.RegionProxy
m_log.ErrorFormat("[PROXY] BeginReceiveFrom failed, retrying... {0}", sd.clientEP); m_log.ErrorFormat("[PROXY] BeginReceiveFrom failed, retrying... {0}", sd.clientEP);
m_log.Error("[PROXY]" + e.Message); m_log.Error("[PROXY]" + e.Message);
m_log.Error("[PROXY]" + e.StackTrace); m_log.Error("[PROXY]" + e.StackTrace);
OpenPort(sd); OpenPort(sd);
} }
} }
} }
@ -471,7 +416,6 @@ namespace OpenSim.ApplicationPlugins.RegionProxy
m_log.Error("[PROXY]" + e.StackTrace); m_log.Error("[PROXY]" + e.StackTrace);
return; return;
} }
} }
else else
{ {
@ -480,7 +424,8 @@ namespace OpenSim.ApplicationPlugins.RegionProxy
ProxyMap.RegionData rd = proxy_map.GetRegionData(sd.clientEP); ProxyMap.RegionData rd = proxy_map.GetRegionData(sd.clientEP);
foreach (EndPoint region in rd.regions) foreach (EndPoint region in rd.regions)
{ {
if(rd.isBlocked) { if (rd.isBlocked)
{
rd.storedMessages.Enqueue(new StoredMessage(buffer, length, numBytes, senderEP, sd)); rd.storedMessages.Enqueue(new StoredMessage(buffer, length, numBytes, senderEP, sd));
} }
else else
@ -502,5 +447,100 @@ namespace OpenSim.ApplicationPlugins.RegionProxy
} }
} }
} }
#region Nested type: ProxyMap
protected class ProxyMap
{
private Dictionary<EndPoint, RegionData> map;
public ProxyMap()
{
map = new Dictionary<EndPoint, RegionData>();
}
public void Add(EndPoint client, EndPoint region)
{
if (map.ContainsKey(client))
{
map[client].regions.Add(region);
}
else
{
RegionData regions = new RegionData();
map.Add(client, regions);
regions.regions.Add(region);
}
}
public RegionData GetRegionData(EndPoint client)
{
return map[client];
}
public EndPoint GetClient(EndPoint region)
{
foreach (KeyValuePair<EndPoint, RegionData> pair in map)
{
if (pair.Value.regions.Contains(region))
{
return pair.Key;
}
}
return null;
}
#region Nested type: RegionData
public class RegionData
{
public bool isBlocked = false;
public List<EndPoint> regions = new List<EndPoint>();
public Queue storedMessages = new Queue();
}
#endregion
}
#endregion
#region Nested type: ServerData
protected class ServerData
{
public EndPoint clientEP;
public byte[] recvBuffer = new byte[4096];
public EndPoint senderEP;
public Socket server;
public IPEndPoint serverIP;
public ServerData()
{
server = null;
}
}
#endregion
#region Nested type: StoredMessage
protected class StoredMessage
{
public byte[] buffer;
public int length;
public ServerData sd;
public EndPoint senderEP;
public StoredMessage(byte[] buffer, int length, int maxLength, EndPoint senderEP, ServerData sd)
{
this.buffer = new byte[maxLength];
this.length = length;
for (int i = 0; i < length; i++) this.buffer[i] = buffer[i];
this.senderEP = senderEP;
this.sd = sd;
}
}
#endregion
} }
} }