From 1506846d36bcaefb418baa03661f7c86202873ff Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Fri, 13 Mar 2009 08:57:52 +0000 Subject: [PATCH] * All nine regions in Simian come online at startup now (one step at a time) git-svn-id: http://libopenmetaverse.googlecode.com/svn/libopenmetaverse/trunk@2484 52acb1d6-8a22-11de-b505-999d5b087335 --- Programs/Simian/Extensions/GridLocal.cs | 48 ++++++---- Programs/Simian/Extensions/SceneManager.cs | 5 +- Programs/Simian/Interfaces/IGridProvider.cs | 17 ++-- Programs/Simian/Interfaces/ISceneProvider.cs | 2 +- Programs/Simian/Simian.cs | 86 ++++++++++++++++-- bin/SimianData/JunkRegionCertificate.p12 | Bin 0 -> 1906 bytes bin/SimianData/RegionConfig/Baboon.ini | 9 +- bin/SimianData/RegionConfig/Capuchin.ini | 9 +- bin/SimianData/RegionConfig/Chimpanzee.ini | 9 +- bin/SimianData/RegionConfig/Macaque.ini | 9 +- bin/SimianData/RegionConfig/Mandrill.ini | 9 +- bin/SimianData/RegionConfig/Marmoset.ini | 9 +- bin/SimianData/RegionConfig/Orangutan.ini | 9 +- bin/SimianData/RegionConfig/Spider Monkey.ini | 9 +- bin/SimianData/RegionConfig/Tamarin.ini | 9 +- bin/SimianData/Simian.ini | 18 ++-- 16 files changed, 195 insertions(+), 62 deletions(-) create mode 100644 bin/SimianData/JunkRegionCertificate.p12 diff --git a/Programs/Simian/Extensions/GridLocal.cs b/Programs/Simian/Extensions/GridLocal.cs index 097eeee1..746be501 100644 --- a/Programs/Simian/Extensions/GridLocal.cs +++ b/Programs/Simian/Extensions/GridLocal.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Security.Cryptography.X509Certificates; using ExtensionLoader; using OpenMetaverse; @@ -7,6 +9,7 @@ namespace Simian public class GridLocal : IExtension, IGridProvider { Simian server; + DoubleDictionary grid = new DoubleDictionary(); public GridLocal() { @@ -22,41 +25,52 @@ namespace Simian { } - public bool TryRegisterGridSpace(RegionInfo region, out UUID regionID) + public bool TryRegisterGridSpace(RegionInfo regionInfo, X509Certificate2 regionCert, out UUID regionID) + { + // No need to check the certificate since the requests are all local + + // Check the coordinates + if (!grid.ContainsKey(regionInfo.Handle)) + { + regionID = UUID.Random(); + grid.Add(regionInfo.Handle, regionID, regionInfo); + return true; + } + else + { + regionID = UUID.Zero; + return false; + } + } + + public bool TryRegisterAnyGridSpace(RegionInfo region, X509Certificate2 regionCert, bool isolated, out UUID regionID) { regionID = UUID.Zero; return false; } - public bool TryRegisterAnyGridSpace(RegionInfo region, bool isolated, out UUID regionID) + public bool UnregisterGridSpace(UUID regionID, X509Certificate2 regionCert) { - regionID = UUID.Zero; - return false; + return grid.Remove(regionID); } - public bool UnregisterGridSpace(RegionInfo region) - { - return false; - } - - public void RegionUpdate(RegionInfo region) + public void RegionUpdate(UUID regionID, X509Certificate2 regionCert) { } - public void RegionHeartbeat(RegionInfo region) + public void RegionHeartbeat(UUID regionID, X509Certificate2 regionCert) { } - public bool TryGetRegion(UUID regionID, out RegionInfo region) + public bool TryGetRegion(UUID regionID, X509Certificate2 regionCert, out RegionInfo region) { - region = null; - return false; + return grid.TryGetValue(regionID, out region); } - public bool TryGetRegion(uint x, uint y, out RegionInfo region) + public bool TryGetRegion(uint regionX, uint regionY, X509Certificate2 regionCert, out RegionInfo region) { - region = null; - return false; + ulong handle = Utils.UIntsToLong(256 * regionX, 256 * regionY); + return grid.TryGetValue(handle, out region); } public ISceneProvider GetDefaultLocalScene() diff --git a/Programs/Simian/Extensions/SceneManager.cs b/Programs/Simian/Extensions/SceneManager.cs index 0f85ea1a..403c6de9 100644 --- a/Programs/Simian/Extensions/SceneManager.cs +++ b/Programs/Simian/Extensions/SceneManager.cs @@ -124,12 +124,13 @@ namespace Simian { } - public bool Start(Simian server, string name, IPEndPoint endpoint, uint regionX, uint regionY, + public bool Start(Simian server, string name, IPEndPoint endpoint, UUID regionID, uint regionX, uint regionY, string defaultTerrainFile, int staticObjects, int physicalObjects) { this.server = server; this.regionName = name; this.endpoint = endpoint; + this.regionID = regionID; // Set the properties because this will automatically update the regionHandle RegionX = regionX; @@ -176,6 +177,8 @@ namespace Simian if (!String.IsNullOrEmpty(defaultTerrainFile)) LoadTerrain(Simian.DATA_DIR + defaultTerrainFile); + Logger.Log(String.Format("Region {0} online at ({1},{2}) listening on {3}", name, regionX, regionY, endpoint), + Helpers.LogLevel.Info); return true; } diff --git a/Programs/Simian/Interfaces/IGridProvider.cs b/Programs/Simian/Interfaces/IGridProvider.cs index 6d5610f2..a5da1ff0 100644 --- a/Programs/Simian/Interfaces/IGridProvider.cs +++ b/Programs/Simian/Interfaces/IGridProvider.cs @@ -1,5 +1,6 @@ using System; using System.Net; +using System.Security.Cryptography.X509Certificates; using OpenMetaverse; using OpenMetaverse.StructuredData; @@ -88,7 +89,7 @@ namespace Simian public interface IGridProvider { - bool TryRegisterGridSpace(RegionInfo region, out UUID regionID); + bool TryRegisterGridSpace(RegionInfo regionInfo, X509Certificate2 regionCert, out UUID regionID); /// /// Attempts to register any available space closest to the given grid /// coordinates @@ -96,19 +97,21 @@ namespace Simian /// Information about the region to be registered. /// The X, Y, and Handle values may be modified if the exact grid /// coordinate requested is not available + /// SSL client certificate file for the region. + /// Must be signed by the grid server /// If true, the registered grid space must not /// be adjacent to any other regions /// The unique identifier of the registered /// region upon success. This will also be assigned to region.ID /// True if the registration was successful, otherwise false - bool TryRegisterAnyGridSpace(RegionInfo region, bool isolated, out UUID regionID); - bool UnregisterGridSpace(RegionInfo region); + bool TryRegisterAnyGridSpace(RegionInfo region, X509Certificate2 regionCert, bool isolated, out UUID regionID); + bool UnregisterGridSpace(UUID regionID, X509Certificate2 regionCert); - void RegionUpdate(RegionInfo region); - void RegionHeartbeat(RegionInfo region); + void RegionUpdate(UUID regionID, X509Certificate2 regionCert); + void RegionHeartbeat(UUID regionID, X509Certificate2 regionCert); - bool TryGetRegion(UUID regionID, out RegionInfo region); - bool TryGetRegion(uint x, uint y, out RegionInfo region); + bool TryGetRegion(UUID regionID, X509Certificate2 regionCert, out RegionInfo region); + bool TryGetRegion(uint regionX, uint regionY, X509Certificate2 regionCert, out RegionInfo region); /// /// Gets the default scene running on this server diff --git a/Programs/Simian/Interfaces/ISceneProvider.cs b/Programs/Simian/Interfaces/ISceneProvider.cs index 533855bc..205afe91 100644 --- a/Programs/Simian/Interfaces/ISceneProvider.cs +++ b/Programs/Simian/Interfaces/ISceneProvider.cs @@ -149,7 +149,7 @@ namespace Simian uint TerrainPatchCountWidth { get; } uint TerrainPatchCountHeight { get; } - bool Start(Simian server, string name, IPEndPoint endpoint, uint regionX, uint regionY, string defaultTerrainFile, int staticObjects, int physicalObjects); + bool Start(Simian server, string name, IPEndPoint endpoint, UUID regionID, uint regionX, uint regionY, string defaultTerrainFile, int staticObjects, int physicalObjects); void Stop(); void ObjectAddOrUpdate(object sender, SimulationObject obj, UUID ownerID, int scriptStartParam, PrimFlags creatorFlags, UpdateFlags updateFlags); diff --git a/Programs/Simian/Simian.cs b/Programs/Simian/Simian.cs index b666f38b..3cb2e2fd 100644 --- a/Programs/Simian/Simian.cs +++ b/Programs/Simian/Simian.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Net; +using System.Net.Sockets; using System.IO; using System.Text; using System.Xml; @@ -23,6 +24,7 @@ namespace Simian public const string REGION_CONFIG_DIR = DATA_DIR + "RegionConfig/"; public const string ASSET_CACHE_DIR = DATA_DIR + "AssetCache/"; public const string DEFAULT_ASSET_DIR = DATA_DIR + "DefaultAssets/"; + public const int DEFAULT_UDP_PORT = 9000; public Uri HttpUri; public HttpListener HttpServer; @@ -53,6 +55,8 @@ namespace Simian public bool Start() { + IPHostEntry entry; + IPAddress address; IConfig httpConfig; try @@ -74,17 +78,26 @@ namespace Simian int port = httpConfig.GetInt("ListenPort"); string hostname = httpConfig.GetString("Hostname", null); string sslCertFile = httpConfig.GetString("SSLCertFile", null); - IPAddress address = IPAddress.Any; if (String.IsNullOrEmpty(hostname)) { hostname = Dns.GetHostName(); + entry = Dns.GetHostEntry(hostname); + address = IPAddress.Any; } else { - IPHostEntry entry = Dns.GetHostEntry(hostname); + entry = Dns.GetHostEntry(hostname); if (entry != null && entry.AddressList.Length > 0) + { address = entry.AddressList[0]; + } + else + { + Logger.Log("Could not resolve an IP address from hostname " + hostname + ", binding to all interfaces", + Helpers.LogLevel.Warning); + address = IPAddress.Any; + } } if (!String.IsNullOrEmpty(sslCertFile)) @@ -173,25 +186,80 @@ namespace Simian uint regionX, regionY; UInt32.TryParse(regionConfig.GetString("RegionX", "0"), out regionX); UInt32.TryParse(regionConfig.GetString("RegionY", "0"), out regionY); + string certFile = regionConfig.GetString("RegionCertificate", null); int staticObjectLimit = regionConfig.GetInt("StaticObjectLimit", 0); int physicalObjectLimit = regionConfig.GetInt("PhysicalObjectLimit", 0); - if (String.IsNullOrEmpty(name) || regionX == 0 || regionY == 0) + if (String.IsNullOrEmpty(name) || regionX == 0 || regionY == 0 || String.IsNullOrEmpty(certFile)) { Logger.Log("Incomplete information in " + configFiles[i] + ", skipping", Helpers.LogLevel.Warning); continue; } - // Get the IPEndPoint for this region - IPEndPoint endpoint = new IPEndPoint(IPAddress.Any, 9000); + #region IPEndPoint Assignment + + IPEndPoint endpoint; + + if (udpPort != 0) + { + endpoint = new IPEndPoint(address, udpPort); + } + else + { + udpPort = DEFAULT_UDP_PORT; + + while (true) + { + endpoint = new IPEndPoint(address, udpPort); + Socket udpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); + try + { + udpSocket.Bind(endpoint); + udpSocket.Close(); + break; + } + catch (SocketException) + { + ++udpPort; + } + } + } + + #endregion IPEndPoint Assignment + + #region Grid Registration + + X509Certificate2 regionCert; + + try + { + regionCert = new X509Certificate2(DATA_DIR + certFile); + } + catch (Exception) + { + Logger.Log("Failed to load region certificate file from " + certFile, Helpers.LogLevel.Error); + continue; + } + + RegionInfo info = new RegionInfo(); + info.Handle = Utils.UIntsToLong(256 * regionX, 256 * regionY); + info.HttpServer = HttpUri; + info.IPAndPort = endpoint; + info.Name = name; + info.Online = true; + + if (!Grid.TryRegisterGridSpace(info, regionCert, out info.ID)) + { + Logger.Log("Failed to register grid space for region " + name, Helpers.LogLevel.Error); + continue; + } + + #endregion Grid Registration // TODO: Support non-SceneManager scenes? ISceneProvider scene = new SceneManager(); - scene.Start(this, name, endpoint, regionX, regionY, defaultTerrain, staticObjectLimit, physicalObjectLimit); + scene.Start(this, name, endpoint, info.ID, regionX, regionY, defaultTerrain, staticObjectLimit, physicalObjectLimit); Scenes.Add(scene); - - // FIXME: Use IGridProvider to actually register the scenes into spaces - break; } } catch (Exception ex) diff --git a/bin/SimianData/JunkRegionCertificate.p12 b/bin/SimianData/JunkRegionCertificate.p12 new file mode 100644 index 0000000000000000000000000000000000000000..808a2ad9bbdd5c6f8b6a46f8dfefaf5c3fef2b55 GIT binary patch literal 1906 zcmZXUX*3&%8ipkziBL778jPhwP-~)EDvPaZ-zo@AY(?E#lJ?qKYDp<=s4;d`6|Jq+ zP_;CTt#;MLHdO7V_PQuSg&1?ry?5?8_s4g>bDsBn@2~GXC>kUf2;fK2AXmYHs&~!r z?i>R^0EILN5k!L!j<7w72J-kj0vFOie<5oifbVFT{+$3&KZ9ZaZV*0d6ahg$jb$&F z`dbVDfsnpf8VCVL-mzve!i}`Gei)x4CYEr%c)nNfPc5++LpNoSZwO0dgiCYi4|ZQ) zajQomF0JKh31uIOirgDn(mc4dC@V|4ERoa!A@`fvGRvMdx0+poX*9sneSV1>{A>fVY-Qcd423O9P*()Sdu} zCjClU9cG_b6GCA5z;&B}MeRf^G($XhxHfH$RA^j)g8s2<)`n?n zit%Vlh!#c@OW&TE|ax?usyLVyEfXO2wL}P@b?k3D>O%xLz1mfFr?uHx@Y!_$*B7m zre|gZ)-AaW`t=iN>N>6|%qc&0&;0bqroFsmP;`ppQl31CD0GlWMM_>=T^!ZZ5OJKq z*gQ&CD#}N&x^bC9zpfO@*eN0?ulwfOqK8W~SwwOCVBFW%?Y6ewexM_GbGdWaQV(1m zZT?}SEKNP#0O|bPQoSrbF4DoTn?(hD^o!HbNRnR&ba6IndI8AmFRS{ZPysuX98l(3 zRNv$mt-rsG%M?@Zl?Zh%oRppq>?&7mErLoFs6;ii;tU>C3Z2QSVw}}9joxae!}Zs8 zpKDj=O?V_(3AE)cPF1)o&NFn}9xiuV%2)*Lyq?;^er5%UZ7K!b6XrHAcWWkBqFKEj z{y(7FKrzgG3jre=~ zcZ_6K%)a_`S&3c3A1~PyORNP47V&JjZdN!|ifJYZ#UT7Is!dPYuo?KoA+J&7z!;WK zs~%h8H_xbGSqZj!C_uVoZ-(nn{42Ujp!is$hAzj!C|}XPtth0;_8>ib(2$T8{127m z=OvLw?-iKDw|wIND298tZhVhwwKa$JRm9w3$E-rwtWU116g86wQg%n5`wB;jKvqE!7Iggi;&YXOAZTUGQiKGwl<#`|KUFPqRnW*i;Wd#!*jl>B4c%1n3QZBTCqrp!T1)Q+|`N?Pv9yl zr%vDkJ)RM4k2gwuv5%gA6+S2Kwma4ntEPWT)MsQsdZGVHggo}Px7*E$joBC(*X$cb zHO*5z4V}w8*Z%6=u`sjDNW&0SIXDtFYi!`0VUnAvrvR`gzwpWkurH*B2v3H%wqLy( z+b>gp(Y>~jauA840hj(qB!x8K7Z43Ne1r#%<|A0>KU#qSfJb4;5iI(D+f>nwcRYhP zhW@h6(Rr-F)0mt!32J3A%vWvAqXIh7*fUs*$2WdLzPn|P2)E^zK*2{1Vkvp&db0|w z-sFCk%ctnzRkf~&!DeWwZumqG!S*J{cZ$5zefDuD z{(X?T>^*+Cm*yCfZzJn8b z3=`f5{@mvEYfXuvT7m7 za62U-8LhP{1otLfyS8B)>^d}mTU{IG=1@GYg*o-gK?GG(&2CTfr3M)XWvV@kfA|~E zS4L_5LpqNjEYh=c%OO7?3-Bq<*04m{S<%iZY9*_lcHJ#)+#`KK?f3iDI?v8(`Taa( z_uHvR7e>}kZ4F^u4zE&HtNG%au*B1*IW?}LJqs@@{75Zf%pdq!u3hd`6%u80`q)~W zTm`+k?}R{$os~`bAjsYRah2FeU`dNG@|p^6kdoqa?zwbVADlWG*uHum^>&QORd%pT z2#X9XYP#D~m>5*_D8+QLI8GF&d_Cu829WoWdEvSOM=2dk4&B1EchzwuS{mdE(B&ep zT%Dmq4XNX|;Vb9*@GdSjR^MAVixH~@lZ}rqY%BQVC)sb1r4Bu3K&W!XJ=f`U$kW| zyoKc1=v8?WY-KLBcuvDTc5AzvV{_-neQ^>|mNDnRZarCFPUxlP;?sT!z)}P9ofAjA p&J-VhW^}8cT9KaF4?O8?_(r*95Pbp#|L<1|o