OGS1GridServices.cs 63 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510
  1. /*
  2. * Copyright (c) Contributors, http://opensimulator.org/
  3. * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the OpenSim Project nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. using System;
  28. using System.Collections;
  29. using System.Collections.Generic;
  30. using System.Net;
  31. using System.Net.Sockets;
  32. using System.Reflection;
  33. using System.Runtime.Remoting;
  34. using System.Runtime.Remoting.Channels;
  35. using System.Runtime.Remoting.Channels.Tcp;
  36. using System.Security.Authentication;
  37. using System.Threading;
  38. using libsecondlife;
  39. using log4net;
  40. using Nwc.XmlRpc;
  41. using OpenSim.Framework;
  42. using OpenSim.Framework.Communications;
  43. using OpenSim.Framework.Servers;
  44. using OpenSim.Region.Communications.Local;
  45. namespace OpenSim.Region.Communications.OGS1
  46. {
  47. public class OGS1GridServices : IGridServices, IInterRegionCommunications
  48. {
  49. private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  50. private LocalBackEndServices m_localBackend = new LocalBackEndServices();
  51. private Dictionary<ulong, RegionInfo> m_remoteRegionInfoCache = new Dictionary<ulong, RegionInfo>();
  52. private List<SimpleRegionInfo> m_knownRegions = new List<SimpleRegionInfo>();
  53. private Dictionary<ulong, int> m_deadRegionCache = new Dictionary<ulong, int>();
  54. private Dictionary<string, string> m_queuedGridSettings = new Dictionary<string, string>();
  55. public BaseHttpServer httpListener;
  56. public NetworkServersInfo serversInfo;
  57. public BaseHttpServer httpServer;
  58. public string _gdebugRegionName = String.Empty;
  59. public string gdebugRegionName
  60. {
  61. get { return _gdebugRegionName; }
  62. set { _gdebugRegionName = value; }
  63. }
  64. public string _rdebugRegionName = String.Empty;
  65. public string rdebugRegionName
  66. {
  67. get { return _rdebugRegionName; }
  68. set { _rdebugRegionName = value; }
  69. }
  70. /// <summary>
  71. /// Contructor. Adds "expect_user" and "check" xmlrpc method handlers
  72. /// </summary>
  73. /// <param name="servers_info"></param>
  74. /// <param name="httpServe"></param>
  75. public OGS1GridServices(NetworkServersInfo servers_info, BaseHttpServer httpServe)
  76. {
  77. serversInfo = servers_info;
  78. httpServer = httpServe;
  79. //Respond to Grid Services requests
  80. httpServer.AddXmlRPCHandler("expect_user", ExpectUser);
  81. httpServer.AddXmlRPCHandler("check", PingCheckReply);
  82. StartRemoting();
  83. }
  84. // see IGridServices
  85. public RegionCommsListener RegisterRegion(RegionInfo regionInfo)
  86. {
  87. m_log.InfoFormat(
  88. "[OGS1 GRID SERVICES]: Attempting to register region {0} with grid at {1}",
  89. regionInfo.RegionName, serversInfo.GridURL);
  90. Hashtable GridParams = new Hashtable();
  91. // Login / Authentication
  92. GridParams["authkey"] = serversInfo.GridSendKey;
  93. GridParams["recvkey"] = serversInfo.GridRecvKey;
  94. GridParams["UUID"] = regionInfo.RegionID.ToString();
  95. GridParams["sim_ip"] = regionInfo.ExternalHostName;
  96. GridParams["sim_port"] = regionInfo.InternalEndPoint.Port.ToString();
  97. GridParams["region_locx"] = regionInfo.RegionLocX.ToString();
  98. GridParams["region_locy"] = regionInfo.RegionLocY.ToString();
  99. GridParams["sim_name"] = regionInfo.RegionName;
  100. GridParams["http_port"] = serversInfo.HttpListenerPort.ToString();
  101. GridParams["remoting_port"] = NetworkServersInfo.RemotingListenerPort.ToString();
  102. GridParams["map-image-id"] = regionInfo.EstateSettings.terrainImageID.ToString();
  103. GridParams["originUUID"] = regionInfo.originRegionID.ToString();
  104. GridParams["server_uri"] = regionInfo.ServerURI;
  105. GridParams["region_secret"] = regionInfo.regionSecret;
  106. // part of an initial brutish effort to provide accurate information (as per the xml region spec)
  107. // wrt the ownership of a given region
  108. // the (very bad) assumption is that this value is being read and handled inconsistently or
  109. // not at all. Current strategy is to put the code in place to support the validity of this information
  110. // and to roll forward debugging any issues from that point
  111. //
  112. // this particular section of the mod attempts to supply a value from the region's xml file to the grid
  113. // server for the UUID of the region's owner (master avatar)
  114. GridParams["master_avatar_uuid"] = regionInfo.MasterAvatarAssignedUUID.ToString();
  115. // Package into an XMLRPC Request
  116. ArrayList SendParams = new ArrayList();
  117. SendParams.Add(GridParams);
  118. // Send Request
  119. XmlRpcResponse GridResp;
  120. try
  121. {
  122. XmlRpcRequest GridReq = new XmlRpcRequest("simulator_login", SendParams);
  123. GridResp = GridReq.Send(serversInfo.GridURL, 30000);
  124. }
  125. catch (Exception e)
  126. {
  127. Exception e2
  128. = new Exception(
  129. String.Format("Unable to connect to grid at {0}. Grid service not running?", serversInfo.GridURL),
  130. e);
  131. throw(e2);
  132. }
  133. Hashtable GridRespData = (Hashtable)GridResp.Value;
  134. Hashtable griddatahash = GridRespData;
  135. // Process Response
  136. if (GridRespData.ContainsKey("error"))
  137. {
  138. string errorstring = (string) GridRespData["error"];
  139. Exception e = new Exception(String.Format("Unable to connect to grid at {0}: {1}", serversInfo.GridURL, errorstring));
  140. throw e;
  141. }
  142. else
  143. {
  144. m_knownRegions = RequestNeighbours(regionInfo.RegionLocX, regionInfo.RegionLocY);
  145. if (GridRespData.ContainsKey("allow_forceful_banlines"))
  146. {
  147. if ((string) GridRespData["allow_forceful_banlines"] != "TRUE")
  148. {
  149. //m_localBackend.SetForcefulBanlistsDisallowed(regionInfo.RegionHandle);
  150. m_queuedGridSettings.Add("allow_forceful_banlines", "FALSE");
  151. }
  152. }
  153. m_log.InfoFormat(
  154. "[OGS1 GRID SERVICES]: Region {0} successfully registered with grid at {1}",
  155. regionInfo.RegionName, serversInfo.GridURL);
  156. }
  157. return m_localBackend.RegisterRegion(regionInfo);
  158. }
  159. public bool DeregisterRegion(RegionInfo regionInfo)
  160. {
  161. Hashtable GridParams = new Hashtable();
  162. GridParams["UUID"] = regionInfo.RegionID.ToString();
  163. // Package into an XMLRPC Request
  164. ArrayList SendParams = new ArrayList();
  165. SendParams.Add(GridParams);
  166. // Send Request
  167. XmlRpcRequest GridReq = new XmlRpcRequest("simulator_after_region_moved", SendParams);
  168. XmlRpcResponse GridResp = GridReq.Send(serversInfo.GridURL, 10000);
  169. Hashtable GridRespData = (Hashtable) GridResp.Value;
  170. Hashtable griddatahash = GridRespData;
  171. // Process Response
  172. if (GridRespData.ContainsKey("error"))
  173. {
  174. string errorstring = (string)GridRespData["error"];
  175. m_log.Error("Unable to connect to grid: " + errorstring);
  176. return false;
  177. }
  178. // What does DeregisterRegion() do?
  179. return m_localBackend.DeregisterRegion(regionInfo);
  180. }
  181. public virtual Dictionary<string, string> GetGridSettings()
  182. {
  183. Dictionary<string, string> returnGridSettings = new Dictionary<string, string>();
  184. lock (m_queuedGridSettings)
  185. {
  186. foreach (string Dictkey in m_queuedGridSettings.Keys)
  187. {
  188. returnGridSettings.Add(Dictkey, m_queuedGridSettings[Dictkey]);
  189. }
  190. m_queuedGridSettings.Clear();
  191. }
  192. return returnGridSettings;
  193. }
  194. // see IGridServices
  195. public List<SimpleRegionInfo> RequestNeighbours(uint x, uint y)
  196. {
  197. Hashtable respData = MapBlockQuery((int) x - 1, (int) y - 1, (int) x + 1, (int) y + 1);
  198. List<SimpleRegionInfo> neighbours = new List<SimpleRegionInfo>();
  199. foreach (ArrayList neighboursList in respData.Values)
  200. {
  201. foreach (Hashtable neighbourData in neighboursList)
  202. {
  203. uint regX = Convert.ToUInt32(neighbourData["x"]);
  204. uint regY = Convert.ToUInt32(neighbourData["y"]);
  205. if ((x != regX) || (y != regY))
  206. {
  207. string simIp = (string) neighbourData["sim_ip"];
  208. uint port = Convert.ToUInt32(neighbourData["sim_port"]);
  209. string externalUri = (string) neighbourData["sim_uri"];
  210. string externalIpStr = String.Empty;
  211. try
  212. {
  213. externalIpStr = Util.GetHostFromDNS(simIp).ToString();
  214. }
  215. catch (SocketException e)
  216. {
  217. m_log.WarnFormat("RequestNeighbours(): Lookup of neighbour {0} failed! Not including in neighbours list. {1}", simIp, e);
  218. continue;
  219. }
  220. SimpleRegionInfo sri = new SimpleRegionInfo(regX, regY, simIp, port);
  221. sri.RemotingPort = Convert.ToUInt32(neighbourData["remoting_port"]);
  222. if (neighbourData.ContainsKey("http_port"))
  223. {
  224. sri.HttpPort = Convert.ToUInt32(neighbourData["http_port"]);
  225. }
  226. sri.RegionID = new LLUUID((string) neighbourData["uuid"]);
  227. neighbours.Add(sri);
  228. }
  229. }
  230. }
  231. return neighbours;
  232. }
  233. /// <summary>
  234. ///
  235. /// </summary>
  236. /// <param name="regionHandle"></param>
  237. /// <returns></returns>
  238. public RegionInfo RequestNeighbourInfo(LLUUID Region_UUID)
  239. {
  240. RegionInfo regionInfo;
  241. Hashtable requestData = new Hashtable();
  242. requestData["region_UUID"] = Region_UUID.ToString();
  243. requestData["authkey"] = serversInfo.GridSendKey;
  244. ArrayList SendParams = new ArrayList();
  245. SendParams.Add(requestData);
  246. XmlRpcRequest GridReq = new XmlRpcRequest("simulator_data_request", SendParams);
  247. XmlRpcResponse GridResp = GridReq.Send(serversInfo.GridURL, 3000);
  248. Hashtable responseData = (Hashtable) GridResp.Value;
  249. if (responseData.ContainsKey("error"))
  250. {
  251. m_log.WarnFormat("[OGS1 GRID SERVICES]: Error received from grid server: {0}", responseData["error"]);
  252. return null;
  253. }
  254. uint regX = Convert.ToUInt32((string) responseData["region_locx"]);
  255. uint regY = Convert.ToUInt32((string) responseData["region_locy"]);
  256. string internalIpStr = (string) responseData["sim_ip"];
  257. uint port = Convert.ToUInt32(responseData["sim_port"]);
  258. string externalUri = (string) responseData["sim_uri"];
  259. IPEndPoint neighbourInternalEndPoint = new IPEndPoint(IPAddress.Parse(internalIpStr), (int) port);
  260. string neighbourExternalUri = externalUri;
  261. regionInfo = new RegionInfo(regX, regY, neighbourInternalEndPoint, internalIpStr);
  262. regionInfo.RemotingPort = Convert.ToUInt32((string) responseData["remoting_port"]);
  263. regionInfo.RemotingAddress = internalIpStr;
  264. if (responseData.ContainsKey("http_port"))
  265. {
  266. regionInfo.HttpPort = Convert.ToUInt32((string) responseData["http_port"]);
  267. }
  268. regionInfo.RegionID = new LLUUID((string) responseData["region_UUID"]);
  269. regionInfo.RegionName = (string) responseData["region_name"];
  270. if (requestData.ContainsKey("regionHandle"))
  271. {
  272. m_remoteRegionInfoCache.Add(Convert.ToUInt64((string) requestData["regionHandle"]), regionInfo);
  273. }
  274. return regionInfo;
  275. }
  276. /// <summary>
  277. ///
  278. /// </summary>
  279. /// <param name="regionHandle"></param>
  280. /// <returns></returns>
  281. public RegionInfo RequestNeighbourInfo(ulong regionHandle)
  282. {
  283. RegionInfo regionInfo = m_localBackend.RequestNeighbourInfo(regionHandle);
  284. if (regionInfo != null)
  285. {
  286. return regionInfo;
  287. }
  288. if (!m_remoteRegionInfoCache.TryGetValue(regionHandle, out regionInfo))
  289. {
  290. try
  291. {
  292. Hashtable requestData = new Hashtable();
  293. requestData["region_handle"] = regionHandle.ToString();
  294. requestData["authkey"] = serversInfo.GridSendKey;
  295. ArrayList SendParams = new ArrayList();
  296. SendParams.Add(requestData);
  297. XmlRpcRequest GridReq = new XmlRpcRequest("simulator_data_request", SendParams);
  298. XmlRpcResponse GridResp = GridReq.Send(serversInfo.GridURL, 3000);
  299. Hashtable responseData = (Hashtable) GridResp.Value;
  300. if (responseData.ContainsKey("error"))
  301. {
  302. m_log.Error("[OGS1 GRID SERVICES]: Error received from grid server: " + responseData["error"]);
  303. return null;
  304. }
  305. uint regX = Convert.ToUInt32((string) responseData["region_locx"]);
  306. uint regY = Convert.ToUInt32((string) responseData["region_locy"]);
  307. string internalIpStr = (string) responseData["sim_ip"];
  308. uint port = Convert.ToUInt32(responseData["sim_port"]);
  309. string externalUri = (string) responseData["sim_uri"];
  310. IPEndPoint neighbourInternalEndPoint = new IPEndPoint(IPAddress.Parse(internalIpStr), (int) port);
  311. string neighbourExternalUri = externalUri;
  312. regionInfo = new RegionInfo(regX, regY, neighbourInternalEndPoint, internalIpStr);
  313. regionInfo.RemotingPort = Convert.ToUInt32((string) responseData["remoting_port"]);
  314. regionInfo.RemotingAddress = internalIpStr;
  315. if (responseData.ContainsKey("http_port"))
  316. {
  317. regionInfo.HttpPort = Convert.ToUInt32((string) responseData["http_port"]);
  318. }
  319. regionInfo.RegionID = new LLUUID((string) responseData["region_UUID"]);
  320. regionInfo.RegionName = (string) responseData["region_name"];
  321. m_remoteRegionInfoCache.Add(regionHandle, regionInfo);
  322. }
  323. catch (WebException)
  324. {
  325. m_log.Error("[OGS1 GRID SERVICES]: " +
  326. "Region lookup failed for: " + regionHandle.ToString() +
  327. " - Is the GridServer down?");
  328. return null;
  329. }
  330. }
  331. return regionInfo;
  332. }
  333. public RegionInfo RequestClosestRegion(string regionName)
  334. {
  335. foreach (RegionInfo ri in m_remoteRegionInfoCache.Values)
  336. {
  337. if (ri.RegionName == regionName)
  338. return ri;
  339. }
  340. RegionInfo regionInfo = null;
  341. try
  342. {
  343. Hashtable requestData = new Hashtable();
  344. requestData["region_name_search"] = regionName;
  345. requestData["authkey"] = serversInfo.GridSendKey;
  346. ArrayList SendParams = new ArrayList();
  347. SendParams.Add(requestData);
  348. XmlRpcRequest GridReq = new XmlRpcRequest("simulator_data_request", SendParams);
  349. XmlRpcResponse GridResp = GridReq.Send(serversInfo.GridURL, 3000);
  350. Hashtable responseData = (Hashtable) GridResp.Value;
  351. if (responseData.ContainsKey("error"))
  352. {
  353. m_log.Error("[OGS1 GRID SERVICES]: Error received from grid server" + responseData["error"]);
  354. return null;
  355. }
  356. uint regX = Convert.ToUInt32((string) responseData["region_locx"]);
  357. uint regY = Convert.ToUInt32((string) responseData["region_locy"]);
  358. string internalIpStr = (string) responseData["sim_ip"];
  359. uint port = Convert.ToUInt32(responseData["sim_port"]);
  360. string externalUri = (string) responseData["sim_uri"];
  361. IPEndPoint neighbourInternalEndPoint = new IPEndPoint(IPAddress.Parse(internalIpStr), (int) port);
  362. string neighbourExternalUri = externalUri;
  363. regionInfo = new RegionInfo(regX, regY, neighbourInternalEndPoint, internalIpStr);
  364. regionInfo.RemotingPort = Convert.ToUInt32((string) responseData["remoting_port"]);
  365. regionInfo.RemotingAddress = internalIpStr;
  366. if (responseData.ContainsKey("http_port"))
  367. {
  368. regionInfo.HttpPort = Convert.ToUInt32((string) responseData["http_port"]);
  369. }
  370. regionInfo.RegionID = new LLUUID((string) responseData["region_UUID"]);
  371. regionInfo.RegionName = (string) responseData["region_name"];
  372. if (!m_remoteRegionInfoCache.ContainsKey(regionInfo.RegionHandle))
  373. m_remoteRegionInfoCache.Add(regionInfo.RegionHandle, regionInfo);
  374. }
  375. catch (WebException)
  376. {
  377. m_log.Error("[OGS1 GRID SERVICES]: " +
  378. "Region lookup failed for: " + regionName +
  379. " - Is the GridServer down?");
  380. }
  381. return regionInfo;
  382. }
  383. /// <summary>
  384. ///
  385. /// </summary>
  386. /// <param name="minX"></param>
  387. /// <param name="minY"></param>
  388. /// <param name="maxX"></param>
  389. /// <param name="maxY"></param>
  390. /// <returns></returns>
  391. public List<MapBlockData> RequestNeighbourMapBlocks(int minX, int minY, int maxX, int maxY)
  392. {
  393. int temp = 0;
  394. if (minX > maxX)
  395. {
  396. temp = minX;
  397. minX = maxX;
  398. maxX = temp;
  399. }
  400. if (minY > maxY)
  401. {
  402. temp = minY;
  403. minY = maxY;
  404. maxY = temp;
  405. }
  406. Hashtable respData = MapBlockQuery(minX, minY, maxX, maxY);
  407. List<MapBlockData> neighbours = new List<MapBlockData>();
  408. foreach (ArrayList a in respData.Values)
  409. {
  410. foreach (Hashtable n in a)
  411. {
  412. MapBlockData neighbour = new MapBlockData();
  413. neighbour.X = Convert.ToUInt16(n["x"]);
  414. neighbour.Y = Convert.ToUInt16(n["y"]);
  415. neighbour.Name = (string) n["name"];
  416. neighbour.Access = Convert.ToByte(n["access"]);
  417. neighbour.RegionFlags = Convert.ToUInt32(n["region-flags"]);
  418. neighbour.WaterHeight = Convert.ToByte(n["water-height"]);
  419. neighbour.MapImageId = new LLUUID((string) n["map-image-id"]);
  420. neighbours.Add(neighbour);
  421. }
  422. }
  423. return neighbours;
  424. }
  425. /// <summary>
  426. /// Performs a XML-RPC query against the grid server returning mapblock information in the specified coordinates
  427. /// </summary>
  428. /// <remarks>REDUNDANT - OGS1 is to be phased out in favour of OGS2</remarks>
  429. /// <param name="minX">Minimum X value</param>
  430. /// <param name="minY">Minimum Y value</param>
  431. /// <param name="maxX">Maximum X value</param>
  432. /// <param name="maxY">Maximum Y value</param>
  433. /// <returns>Hashtable of hashtables containing map data elements</returns>
  434. private Hashtable MapBlockQuery(int minX, int minY, int maxX, int maxY)
  435. {
  436. Hashtable param = new Hashtable();
  437. param["xmin"] = minX;
  438. param["ymin"] = minY;
  439. param["xmax"] = maxX;
  440. param["ymax"] = maxY;
  441. IList parameters = new ArrayList();
  442. parameters.Add(param);
  443. try
  444. {
  445. XmlRpcRequest req = new XmlRpcRequest("map_block", parameters);
  446. XmlRpcResponse resp = req.Send(serversInfo.GridURL, 10000);
  447. Hashtable respData = (Hashtable) resp.Value;
  448. return respData;
  449. }
  450. catch (Exception e)
  451. {
  452. m_log.Error("MapBlockQuery XMLRPC failure: " + e.ToString());
  453. return new Hashtable();
  454. }
  455. }
  456. /// <summary>
  457. /// A ping / version check
  458. /// </summary>
  459. /// <param name="request"></param>
  460. /// <returns></returns>
  461. public XmlRpcResponse PingCheckReply(XmlRpcRequest request)
  462. {
  463. XmlRpcResponse response = new XmlRpcResponse();
  464. Hashtable respData = new Hashtable();
  465. respData["online"] = "true";
  466. m_localBackend.PingCheckReply(respData);
  467. response.Value = respData;
  468. return response;
  469. }
  470. // Grid Request Processing
  471. /// <summary>
  472. /// Received from the user server when a user starts logging in. This call allows
  473. /// the region to prepare for direct communication from the client. Sends back an empty
  474. /// xmlrpc response on completion.
  475. /// </summary>
  476. /// <param name="request"></param>
  477. /// <returns></returns>
  478. public XmlRpcResponse ExpectUser(XmlRpcRequest request)
  479. {
  480. m_log.Debug("[CONNECTION DEBUGGING]: Expect User called, starting agent setup ... ");
  481. Hashtable requestData = (Hashtable) request.Params[0];
  482. AgentCircuitData agentData = new AgentCircuitData();
  483. agentData.SessionID = new LLUUID((string) requestData["session_id"]);
  484. agentData.SecureSessionID = new LLUUID((string) requestData["secure_session_id"]);
  485. agentData.firstname = (string) requestData["firstname"];
  486. agentData.lastname = (string) requestData["lastname"];
  487. agentData.AgentID = new LLUUID((string) requestData["agent_id"]);
  488. agentData.circuitcode = Convert.ToUInt32(requestData["circuit_code"]);
  489. agentData.CapsPath = (string) requestData["caps_path"];
  490. if (requestData.ContainsKey("child_agent") && requestData["child_agent"].Equals("1"))
  491. {
  492. m_log.Debug("[CONNECTION DEBUGGING]: Child agent detected");
  493. agentData.child = true;
  494. }
  495. else
  496. {
  497. m_log.Debug("[CONNECTION DEBUGGING]: Main agent detected");
  498. agentData.startpos =
  499. new LLVector3((float)Convert.ToDecimal((string)requestData["startpos_x"]),
  500. (float)Convert.ToDecimal((string)requestData["startpos_y"]),
  501. (float)Convert.ToDecimal((string)requestData["startpos_z"]));
  502. agentData.child = false;
  503. }
  504. ulong regionHandle = Convert.ToUInt64((string) requestData["regionhandle"]);
  505. m_log.Debug("[CONNECTION DEBUGGING]: Triggering welcome for " + agentData.AgentID.ToString() + " into " + regionHandle.ToString());
  506. m_localBackend.TriggerExpectUser(regionHandle, agentData);
  507. m_log.Info("[OGS1 GRID SERVICES]: Welcoming new user...");
  508. return new XmlRpcResponse();
  509. }
  510. #region m_interRegion Comms
  511. /// <summary>
  512. ///
  513. /// </summary>
  514. private void StartRemoting()
  515. {
  516. TcpChannel ch;
  517. try
  518. {
  519. ch = new TcpChannel((int)NetworkServersInfo.RemotingListenerPort);
  520. ChannelServices.RegisterChannel(ch, false); // Disabled security as Mono doesnt support this.
  521. }
  522. catch (Exception ex)
  523. {
  524. m_log.Error("[OGS1 GRID SERVICES]: Exception while attempting to listen on TCP port " + (int)NetworkServersInfo.RemotingListenerPort + ".");
  525. throw (ex);
  526. }
  527. WellKnownServiceTypeEntry wellType =
  528. new WellKnownServiceTypeEntry(typeof (OGS1InterRegionRemoting), "InterRegions",
  529. WellKnownObjectMode.Singleton);
  530. RemotingConfiguration.RegisterWellKnownServiceType(wellType);
  531. InterRegionSingleton.Instance.OnArrival += TriggerExpectAvatarCrossing;
  532. InterRegionSingleton.Instance.OnChildAgent += IncomingChildAgent;
  533. InterRegionSingleton.Instance.OnPrimGroupArrival += IncomingPrim;
  534. InterRegionSingleton.Instance.OnPrimGroupNear += TriggerExpectPrimCrossing;
  535. InterRegionSingleton.Instance.OnRegionUp += TriggerRegionUp;
  536. InterRegionSingleton.Instance.OnChildAgentUpdate += TriggerChildAgentUpdate;
  537. InterRegionSingleton.Instance.OnTellRegionToCloseChildConnection += TriggerTellRegionToCloseChildConnection;
  538. }
  539. #region Methods called by regions in this instance
  540. public bool ChildAgentUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData)
  541. {
  542. int failures = 0;
  543. lock (m_deadRegionCache)
  544. {
  545. if (m_deadRegionCache.ContainsKey(regionHandle))
  546. {
  547. failures = m_deadRegionCache[regionHandle];
  548. }
  549. }
  550. if (failures <= 3)
  551. {
  552. RegionInfo regInfo = null;
  553. try
  554. {
  555. if (m_localBackend.ChildAgentUpdate(regionHandle, cAgentData))
  556. {
  557. return true;
  558. }
  559. regInfo = RequestNeighbourInfo(regionHandle);
  560. if (regInfo != null)
  561. {
  562. //don't want to be creating a new link to the remote instance every time like we are here
  563. bool retValue = false;
  564. OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject(
  565. typeof(OGS1InterRegionRemoting),
  566. "tcp://" + regInfo.RemotingAddress +
  567. ":" + regInfo.RemotingPort +
  568. "/InterRegions");
  569. if (remObject != null)
  570. {
  571. retValue = remObject.ChildAgentUpdate(regionHandle, cAgentData);
  572. }
  573. else
  574. {
  575. m_log.Warn("[OGS1 GRID SERVICES]: remoting object not found");
  576. }
  577. remObject = null;
  578. // m_log.Info("[INTER]: " +
  579. // gdebugRegionName +
  580. // ": OGS1 tried to Update Child Agent data on outside region and got " +
  581. // retValue.ToString());
  582. return retValue;
  583. }
  584. NoteDeadRegion(regionHandle);
  585. return false;
  586. }
  587. catch (RemotingException e)
  588. {
  589. NoteDeadRegion(regionHandle);
  590. m_log.WarnFormat(
  591. "[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}",
  592. regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
  593. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  594. return false;
  595. }
  596. catch (SocketException e)
  597. {
  598. NoteDeadRegion(regionHandle);
  599. m_log.WarnFormat(
  600. "[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}",
  601. regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
  602. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  603. return false;
  604. }
  605. catch (InvalidCredentialException e)
  606. {
  607. NoteDeadRegion(regionHandle);
  608. m_log.WarnFormat(
  609. "[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}",
  610. regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
  611. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  612. return false;
  613. }
  614. catch (AuthenticationException e)
  615. {
  616. NoteDeadRegion(regionHandle);
  617. m_log.WarnFormat(
  618. "[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}",
  619. regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
  620. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  621. return false;
  622. }
  623. catch (Exception e)
  624. {
  625. NoteDeadRegion(regionHandle);
  626. m_log.WarnFormat("[OGS1 GRID SERVICES]: Unable to connect to adjacent region: {0} {1},{2}",
  627. regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
  628. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  629. return false;
  630. }
  631. }
  632. else
  633. {
  634. //m_log.Info("[INTERREGION]: Skipped Sending Child Update to a region because it failed too many times:" + regionHandle.ToString());
  635. return false;
  636. }
  637. }
  638. /// <summary>
  639. ///
  640. /// </summary>
  641. /// <param name="regionHandle"></param>
  642. /// <param name="agentData"></param>
  643. /// <returns></returns>
  644. public bool InformRegionOfChildAgent(ulong regionHandle, AgentCircuitData agentData)
  645. {
  646. RegionInfo regInfo = null;
  647. try
  648. {
  649. if (m_localBackend.InformRegionOfChildAgent(regionHandle, agentData))
  650. {
  651. return true;
  652. }
  653. regInfo = RequestNeighbourInfo(regionHandle);
  654. if (regInfo != null)
  655. {
  656. //don't want to be creating a new link to the remote instance every time like we are here
  657. bool retValue = false;
  658. OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject(
  659. typeof(OGS1InterRegionRemoting),
  660. "tcp://" + regInfo.RemotingAddress +
  661. ":" + regInfo.RemotingPort +
  662. "/InterRegions");
  663. if (remObject != null)
  664. {
  665. retValue = remObject.InformRegionOfChildAgent(regionHandle, new sAgentCircuitData(agentData));
  666. }
  667. else
  668. {
  669. m_log.Warn("[OGS1 GRID SERVICES]: remoting object not found");
  670. }
  671. remObject = null;
  672. m_log.Info("[OGS1 GRID SERVICES]: " +
  673. gdebugRegionName + ": OGS1 tried to InformRegionOfChildAgent for " +
  674. agentData.firstname + " " + agentData.lastname + " and got " +
  675. retValue.ToString());
  676. return retValue;
  677. }
  678. NoteDeadRegion(regionHandle);
  679. return false;
  680. }
  681. catch (RemotingException e)
  682. {
  683. NoteDeadRegion(regionHandle);
  684. m_log.WarnFormat(
  685. "[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}",
  686. regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
  687. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  688. return false;
  689. }
  690. catch (SocketException e)
  691. {
  692. NoteDeadRegion(regionHandle);
  693. m_log.WarnFormat(
  694. "[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}",
  695. regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
  696. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  697. return false;
  698. }
  699. catch (InvalidCredentialException e)
  700. {
  701. NoteDeadRegion(regionHandle);
  702. m_log.WarnFormat(
  703. "[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}",
  704. regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
  705. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  706. return false;
  707. }
  708. catch (AuthenticationException e)
  709. {
  710. NoteDeadRegion(regionHandle);
  711. m_log.WarnFormat(
  712. "[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}",
  713. regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
  714. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  715. return false;
  716. }
  717. catch (Exception e)
  718. {
  719. NoteDeadRegion(regionHandle);
  720. m_log.WarnFormat(
  721. "[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}",
  722. regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
  723. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  724. return false;
  725. }
  726. }
  727. // UGLY!
  728. public bool RegionUp(SerializableRegionInfo region, ulong regionhandle)
  729. {
  730. SerializableRegionInfo regInfo = null;
  731. try
  732. {
  733. // You may ask why this is in here...
  734. // The region asking the grid services about itself..
  735. // And, surprisingly, the reason is.. it doesn't know
  736. // it's own remoting port! How special.
  737. RegionUpData regiondata = new RegionUpData(region.RegionLocX, region.RegionLocY, region.ExternalHostName, region.InternalEndPoint.Port);
  738. region = new SerializableRegionInfo(RequestNeighbourInfo(region.RegionHandle));
  739. region.RemotingAddress = region.ExternalHostName;
  740. region.RemotingPort = NetworkServersInfo.RemotingListenerPort;
  741. region.HttpPort = serversInfo.HttpListenerPort;
  742. if (m_localBackend.RegionUp(region, regionhandle))
  743. {
  744. return true;
  745. }
  746. regInfo = new SerializableRegionInfo(RequestNeighbourInfo(regionhandle));
  747. if (regInfo != null)
  748. {
  749. // If we're not trying to remote to ourselves.
  750. if (regInfo.RemotingAddress != region.RemotingAddress && region.RemotingAddress != null)
  751. {
  752. //don't want to be creating a new link to the remote instance every time like we are here
  753. bool retValue = false;
  754. OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting) Activator.GetObject(
  755. typeof(OGS1InterRegionRemoting),
  756. "tcp://" +
  757. regInfo.RemotingAddress +
  758. ":" + regInfo.RemotingPort +
  759. "/InterRegions");
  760. if (remObject != null)
  761. {
  762. retValue = remObject.RegionUp(regiondata, regionhandle);
  763. }
  764. else
  765. {
  766. m_log.Warn("[OGS1 GRID SERVICES]: remoting object not found");
  767. }
  768. remObject = null;
  769. m_log.Info("[INTER]: " + gdebugRegionName + ": OGS1 tried to inform region I'm up");
  770. return retValue;
  771. }
  772. else
  773. {
  774. // We're trying to inform ourselves via remoting.
  775. // This is here because we're looping over the listeners before we get here.
  776. // Odd but it should work.
  777. return true;
  778. }
  779. }
  780. return false;
  781. }
  782. catch (RemotingException e)
  783. {
  784. m_log.Warn("[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region using tcp://" +
  785. regInfo.RemotingAddress +
  786. ":" + regInfo.RemotingPort +
  787. "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY +
  788. " - Is this neighbor up?");
  789. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  790. return false;
  791. }
  792. catch (SocketException e)
  793. {
  794. m_log.Warn("[OGS1 GRID SERVICES]: Socket Error: Unable to connect to adjacent region using tcp://" +
  795. regInfo.RemotingAddress +
  796. ":" + regInfo.RemotingPort +
  797. "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY +
  798. " - Is this neighbor up?");
  799. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  800. return false;
  801. }
  802. catch (InvalidCredentialException e)
  803. {
  804. m_log.Warn("[OGS1 GRID SERVICES]: Invalid Credentials: Unable to connect to adjacent region using tcp://" +
  805. regInfo.RemotingAddress +
  806. ":" + regInfo.RemotingPort +
  807. "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY);
  808. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  809. return false;
  810. }
  811. catch (AuthenticationException e)
  812. {
  813. m_log.Warn("[OGS1 GRID SERVICES]: Authentication exception: Unable to connect to adjacent region using tcp://" +
  814. regInfo.RemotingAddress +
  815. ":" + regInfo.RemotingPort +
  816. "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY);
  817. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  818. return false;
  819. }
  820. catch (Exception e)
  821. {
  822. // This line errors with a Null Reference Exception.. Why? @.@
  823. //m_log.Warn("Unknown exception: Unable to connect to adjacent region using tcp://" + regInfo.RemotingAddress +
  824. // ":" + regInfo.RemotingPort +
  825. //"/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY + " - This is likely caused by an incompatibility in the protocol between this sim and that one");
  826. m_log.Debug(e.ToString());
  827. return false;
  828. }
  829. }
  830. /// <summary>
  831. ///
  832. /// </summary>
  833. /// <param name="regionHandle"></param>
  834. /// <param name="agentData"></param>
  835. /// <returns></returns>
  836. public bool InformRegionOfPrimCrossing(ulong regionHandle, LLUUID primID, string objData, int XMLMethod)
  837. {
  838. int failures = 0;
  839. lock (m_deadRegionCache)
  840. {
  841. if (m_deadRegionCache.ContainsKey(regionHandle))
  842. {
  843. failures = m_deadRegionCache[regionHandle];
  844. }
  845. }
  846. if (failures <= 1)
  847. {
  848. RegionInfo regInfo = null;
  849. try
  850. {
  851. if (m_localBackend.InformRegionOfPrimCrossing(regionHandle, primID, objData, XMLMethod))
  852. {
  853. return true;
  854. }
  855. regInfo = RequestNeighbourInfo(regionHandle);
  856. if (regInfo != null)
  857. {
  858. //don't want to be creating a new link to the remote instance every time like we are here
  859. bool retValue = false;
  860. OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject(
  861. typeof(OGS1InterRegionRemoting),
  862. "tcp://" + regInfo.RemotingAddress +
  863. ":" + regInfo.RemotingPort +
  864. "/InterRegions");
  865. if (remObject != null)
  866. {
  867. retValue = remObject.InformRegionOfPrimCrossing(regionHandle, primID.UUID, objData, XMLMethod);
  868. }
  869. else
  870. {
  871. m_log.Warn("[OGS1 GRID SERVICES]: Remoting object not found");
  872. }
  873. remObject = null;
  874. return retValue;
  875. }
  876. NoteDeadRegion(regionHandle);
  877. return false;
  878. }
  879. catch (RemotingException e)
  880. {
  881. NoteDeadRegion(regionHandle);
  882. m_log.Warn("[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region: " + regionHandle);
  883. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  884. return false;
  885. }
  886. catch (SocketException e)
  887. {
  888. NoteDeadRegion(regionHandle);
  889. m_log.Warn("[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region: " + regionHandle);
  890. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  891. return false;
  892. }
  893. catch (InvalidCredentialException e)
  894. {
  895. NoteDeadRegion(regionHandle);
  896. m_log.Warn("[OGS1 GRID SERVICES]: Invalid Credential Exception: Invalid Credentials : " + regionHandle);
  897. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  898. return false;
  899. }
  900. catch (AuthenticationException e)
  901. {
  902. NoteDeadRegion(regionHandle);
  903. m_log.Warn("[OGS1 GRID SERVICES]: Authentication exception: Unable to connect to adjacent region: " + regionHandle);
  904. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  905. return false;
  906. }
  907. catch (Exception e)
  908. {
  909. NoteDeadRegion(regionHandle);
  910. m_log.Warn("[OGS1 GRID SERVICES]: Unknown exception: Unable to connect to adjacent region: " + regionHandle);
  911. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0}", e);
  912. return false;
  913. }
  914. }
  915. else
  916. {
  917. return false;
  918. }
  919. }
  920. /// <summary>
  921. ///
  922. /// </summary>
  923. /// <param name="regionHandle"></param>
  924. /// <param name="agentID"></param>
  925. /// <param name="position"></param>
  926. /// <returns></returns>
  927. public bool ExpectAvatarCrossing(ulong regionHandle, LLUUID agentID, LLVector3 position, bool isFlying)
  928. {
  929. RegionInfo regInfo = null;
  930. try
  931. {
  932. if (m_localBackend.TriggerExpectAvatarCrossing(regionHandle, agentID, position, isFlying))
  933. {
  934. return true;
  935. }
  936. regInfo = RequestNeighbourInfo(regionHandle);
  937. if (regInfo != null)
  938. {
  939. bool retValue = false;
  940. OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting) Activator.GetObject(
  941. typeof (OGS1InterRegionRemoting),
  942. "tcp://" + regInfo.RemotingAddress +
  943. ":" + regInfo.RemotingPort +
  944. "/InterRegions");
  945. if (remObject != null)
  946. {
  947. retValue =
  948. remObject.ExpectAvatarCrossing(regionHandle, agentID.UUID, new sLLVector3(position),
  949. isFlying);
  950. }
  951. else
  952. {
  953. m_log.Warn("[OGS1 GRID SERVICES]: Remoting object not found");
  954. }
  955. remObject = null;
  956. return retValue;
  957. }
  958. //TODO need to see if we know about where this region is and use .net remoting
  959. // to inform it.
  960. NoteDeadRegion(regionHandle);
  961. return false;
  962. }
  963. catch (RemotingException e)
  964. {
  965. NoteDeadRegion(regionHandle);
  966. m_log.WarnFormat(
  967. "[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}",
  968. regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
  969. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  970. return false;
  971. }
  972. catch
  973. {
  974. NoteDeadRegion(regionHandle);
  975. return false;
  976. }
  977. }
  978. public bool ExpectPrimCrossing(ulong regionHandle, LLUUID agentID, LLVector3 position, bool isPhysical)
  979. {
  980. RegionInfo regInfo = null;
  981. try
  982. {
  983. if (m_localBackend.TriggerExpectPrimCrossing(regionHandle, agentID, position, isPhysical))
  984. {
  985. return true;
  986. }
  987. regInfo = RequestNeighbourInfo(regionHandle);
  988. if (regInfo != null)
  989. {
  990. bool retValue = false;
  991. OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting) Activator.GetObject(
  992. typeof (OGS1InterRegionRemoting),
  993. "tcp://" + regInfo.RemotingAddress +
  994. ":" + regInfo.RemotingPort +
  995. "/InterRegions");
  996. if (remObject != null)
  997. {
  998. retValue =
  999. remObject.ExpectAvatarCrossing(regionHandle, agentID.UUID, new sLLVector3(position),
  1000. isPhysical);
  1001. }
  1002. else
  1003. {
  1004. m_log.Warn("[OGS1 GRID SERVICES]: Remoting object not found");
  1005. }
  1006. remObject = null;
  1007. return retValue;
  1008. }
  1009. //TODO need to see if we know about where this region is and use .net remoting
  1010. // to inform it.
  1011. NoteDeadRegion(regionHandle);
  1012. return false;
  1013. }
  1014. catch (RemotingException e)
  1015. {
  1016. NoteDeadRegion(regionHandle);
  1017. m_log.Warn("[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region: " + regionHandle);
  1018. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  1019. return false;
  1020. }
  1021. catch (SocketException e)
  1022. {
  1023. NoteDeadRegion(regionHandle);
  1024. m_log.Warn("[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region: " + regionHandle);
  1025. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  1026. return false;
  1027. }
  1028. catch (InvalidCredentialException e)
  1029. {
  1030. NoteDeadRegion(regionHandle);
  1031. m_log.Warn("[OGS1 GRID SERVICES]: Invalid Credential Exception: Invalid Credentials : " + regionHandle);
  1032. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  1033. return false;
  1034. }
  1035. catch (AuthenticationException e)
  1036. {
  1037. NoteDeadRegion(regionHandle);
  1038. m_log.Warn("[OGS1 GRID SERVICES]: Authentication exception: Unable to connect to adjacent region: " + regionHandle);
  1039. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  1040. return false;
  1041. }
  1042. catch (Exception e)
  1043. {
  1044. NoteDeadRegion(regionHandle);
  1045. m_log.Warn("[OGS1 GRID SERVICES]: Unknown exception: Unable to connect to adjacent region: " + regionHandle);
  1046. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0}", e);
  1047. return false;
  1048. }
  1049. }
  1050. public bool TellRegionToCloseChildConnection(ulong regionHandle, LLUUID agentID)
  1051. {
  1052. RegionInfo regInfo = null;
  1053. try
  1054. {
  1055. if (m_localBackend.TriggerTellRegionToCloseChildConnection(regionHandle, agentID))
  1056. {
  1057. return true;
  1058. }
  1059. regInfo = RequestNeighbourInfo(regionHandle);
  1060. if (regInfo != null)
  1061. {
  1062. bool retValue = false;
  1063. OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject(
  1064. typeof(OGS1InterRegionRemoting),
  1065. "tcp://" + regInfo.RemotingAddress +
  1066. ":" + regInfo.RemotingPort +
  1067. "/InterRegions");
  1068. if (remObject != null)
  1069. {
  1070. retValue =
  1071. remObject.TellRegionToCloseChildConnection(regionHandle, agentID.UUID);
  1072. }
  1073. else
  1074. {
  1075. m_log.Warn("[OGS1 GRID SERVICES]: Remoting object not found");
  1076. }
  1077. remObject = null;
  1078. return true;
  1079. }
  1080. //TODO need to see if we know about where this region is and use .net remoting
  1081. // to inform it.
  1082. NoteDeadRegion(regionHandle);
  1083. return false;
  1084. }
  1085. catch (RemotingException)
  1086. {
  1087. NoteDeadRegion(regionHandle);
  1088. m_log.Warn("[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region to tell it to close child agents: " + regInfo.RegionName +
  1089. " " + regInfo.RegionLocX + "," + regInfo.RegionLocY);
  1090. //m_log.Debug(e.ToString());
  1091. return false;
  1092. }
  1093. catch (SocketException e)
  1094. {
  1095. NoteDeadRegion(regionHandle);
  1096. m_log.Warn("[OGS1 GRID SERVICES]: Socket Error: Unable to connect to adjacent region using tcp://" +
  1097. regInfo.RemotingAddress +
  1098. ":" + regInfo.RemotingPort +
  1099. "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY +
  1100. " - Is this neighbor up?");
  1101. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  1102. return false;
  1103. }
  1104. catch (InvalidCredentialException e)
  1105. {
  1106. NoteDeadRegion(regionHandle);
  1107. m_log.Warn("[OGS1 GRID SERVICES]: Invalid Credentials: Unable to connect to adjacent region using tcp://" +
  1108. regInfo.RemotingAddress +
  1109. ":" + regInfo.RemotingPort +
  1110. "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY);
  1111. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  1112. return false;
  1113. }
  1114. catch (AuthenticationException e)
  1115. {
  1116. NoteDeadRegion(regionHandle);
  1117. m_log.Warn("[OGS1 GRID SERVICES]: Authentication exception: Unable to connect to adjacent region using tcp://" +
  1118. regInfo.RemotingAddress +
  1119. ":" + regInfo.RemotingPort +
  1120. "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY);
  1121. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  1122. return false;
  1123. }
  1124. catch (WebException e)
  1125. {
  1126. NoteDeadRegion(regionHandle);
  1127. m_log.Warn("[OGS1 GRID SERVICES]: WebException exception: Unable to connect to adjacent region using tcp://" +
  1128. regInfo.RemotingAddress +
  1129. ":" + regInfo.RemotingPort +
  1130. "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY);
  1131. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0} {1}", e.Source, e.Message);
  1132. return false;
  1133. }
  1134. catch (Exception e)
  1135. {
  1136. NoteDeadRegion(regionHandle);
  1137. // This line errors with a Null Reference Exception.. Why? @.@
  1138. //m_log.Warn("Unknown exception: Unable to connect to adjacent region using tcp://" + regInfo.RemotingAddress +
  1139. // ":" + regInfo.RemotingPort +
  1140. //"/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY + " - This is likely caused by an incompatibility in the protocol between this sim and that one");
  1141. m_log.DebugFormat("[OGS1 GRID SERVICES]: {0}", e);
  1142. return false;
  1143. }
  1144. }
  1145. public bool AcknowledgeAgentCrossed(ulong regionHandle, LLUUID agentId)
  1146. {
  1147. return m_localBackend.AcknowledgeAgentCrossed(regionHandle, agentId);
  1148. }
  1149. public bool AcknowledgePrimCrossed(ulong regionHandle, LLUUID primId)
  1150. {
  1151. return m_localBackend.AcknowledgePrimCrossed(regionHandle, primId);
  1152. }
  1153. #endregion
  1154. #region Methods triggered by calls from external instances
  1155. /// <summary>
  1156. ///
  1157. /// </summary>
  1158. /// <param name="regionHandle"></param>
  1159. /// <param name="agentData"></param>
  1160. /// <returns></returns>
  1161. public bool IncomingChildAgent(ulong regionHandle, AgentCircuitData agentData)
  1162. {
  1163. //m_log.Info("[INTER]: " + gdebugRegionName + ": Incoming OGS1 Agent " + agentData.firstname + " " + agentData.lastname);
  1164. try
  1165. {
  1166. return m_localBackend.IncomingChildAgent(regionHandle, agentData);
  1167. }
  1168. catch (RemotingException)
  1169. {
  1170. //m_log.Error("Remoting Error: Unable to connect to adjacent region.\n" + e.ToString());
  1171. return false;
  1172. }
  1173. }
  1174. public bool TriggerRegionUp(RegionUpData regionData, ulong regionhandle)
  1175. {
  1176. m_log.Info("[OGS1 GRID SERVICES]: " +
  1177. gdebugRegionName + "Incoming OGS1 RegionUpReport: " + "(" + regionData.X +
  1178. "," + regionData.Y + "). Giving this region a fresh set of 'dead' tries");
  1179. RegionInfo nRegionInfo = new RegionInfo();
  1180. nRegionInfo.SetEndPoint("127.0.0.1", regionData.PORT);
  1181. nRegionInfo.ExternalHostName = regionData.IPADDR;
  1182. nRegionInfo.RegionLocX = regionData.X;
  1183. nRegionInfo.RegionLocY = regionData.Y;
  1184. try
  1185. {
  1186. lock (m_deadRegionCache)
  1187. {
  1188. if (m_deadRegionCache.ContainsKey(nRegionInfo.RegionHandle))
  1189. {
  1190. m_deadRegionCache.Remove(nRegionInfo.RegionHandle);
  1191. }
  1192. }
  1193. return m_localBackend.TriggerRegionUp(nRegionInfo, regionhandle);
  1194. }
  1195. catch (RemotingException e)
  1196. {
  1197. m_log.Error("[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region.\n" + e.ToString());
  1198. return false;
  1199. }
  1200. }
  1201. public bool TriggerChildAgentUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData)
  1202. {
  1203. //m_log.Info("[INTER]: Incoming OGS1 Child Agent Data Update");
  1204. try
  1205. {
  1206. return m_localBackend.TriggerChildAgentUpdate(regionHandle, cAgentData);
  1207. }
  1208. catch (RemotingException e)
  1209. {
  1210. m_log.Error("[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region.\n" + e.ToString());
  1211. return false;
  1212. }
  1213. }
  1214. /// <summary>
  1215. ///
  1216. /// </summary>
  1217. /// <param name="regionHandle"></param>
  1218. /// <param name="agentData"></param>
  1219. /// <returns></returns>
  1220. public bool IncomingPrim(ulong regionHandle, LLUUID primID, string objData, int XMLMethod)
  1221. {
  1222. // Is this necessary?
  1223. try
  1224. {
  1225. m_localBackend.TriggerExpectPrim(regionHandle, primID, objData, XMLMethod);
  1226. return true;
  1227. //m_localBackend.
  1228. }
  1229. catch (RemotingException e)
  1230. {
  1231. m_log.Error("[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region.\n" + e.ToString());
  1232. return false;
  1233. }
  1234. }
  1235. /// <summary>
  1236. ///
  1237. /// </summary>
  1238. /// <param name="regionHandle"></param>
  1239. /// <param name="agentID"></param>
  1240. /// <param name="position"></param>
  1241. /// <returns></returns>
  1242. public bool TriggerExpectAvatarCrossing(ulong regionHandle, LLUUID agentID, LLVector3 position, bool isFlying)
  1243. {
  1244. try
  1245. {
  1246. return m_localBackend.TriggerExpectAvatarCrossing(regionHandle, agentID, position, isFlying);
  1247. }
  1248. catch (RemotingException e)
  1249. {
  1250. m_log.Error("[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region.\n" + e.ToString());
  1251. return false;
  1252. }
  1253. }
  1254. public bool TriggerExpectPrimCrossing(ulong regionHandle, LLUUID agentID, LLVector3 position, bool isPhysical)
  1255. {
  1256. try
  1257. {
  1258. return m_localBackend.TriggerExpectPrimCrossing(regionHandle, agentID, position, isPhysical);
  1259. }
  1260. catch (RemotingException e)
  1261. {
  1262. m_log.Error("[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to adjacent region.\n" + e.ToString());
  1263. return false;
  1264. }
  1265. }
  1266. public bool TriggerTellRegionToCloseChildConnection(ulong regionHandle, LLUUID agentID)
  1267. {
  1268. try
  1269. {
  1270. return m_localBackend.TriggerTellRegionToCloseChildConnection(regionHandle, agentID);
  1271. }
  1272. catch (RemotingException)
  1273. {
  1274. m_log.Info("[OGS1 GRID SERVICES]: Remoting Error: Unable to connect to neighbour to tell it to close a child connection");
  1275. return false;
  1276. }
  1277. }
  1278. #endregion
  1279. #endregion
  1280. // helper to see if remote region is up
  1281. bool m_bAvailable = false;
  1282. int timeOut = 10; //10 seconds
  1283. public void CheckRegion(string address, uint port)
  1284. {
  1285. m_bAvailable = false;
  1286. IPAddress ia = null;
  1287. IPAddress.TryParse(address, out ia);
  1288. IPEndPoint m_EndPoint = new IPEndPoint(ia, (int)port);
  1289. AsyncCallback ConnectedMethodCallback = new AsyncCallback(ConnectedMethod);
  1290. Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  1291. IAsyncResult ar = socket.BeginConnect(m_EndPoint, ConnectedMethodCallback, socket);
  1292. ar.AsyncWaitHandle.WaitOne(timeOut*1000, false);
  1293. Thread.Sleep(500);
  1294. }
  1295. public bool Available
  1296. {
  1297. get { return m_bAvailable; }
  1298. }
  1299. void ConnectedMethod(IAsyncResult ar)
  1300. {
  1301. Socket socket = (Socket)ar.AsyncState;
  1302. try
  1303. {
  1304. socket.EndConnect(ar);
  1305. m_bAvailable = true;
  1306. }
  1307. catch (Exception)
  1308. {
  1309. }
  1310. socket.Close();
  1311. }
  1312. public void NoteDeadRegion(ulong regionhandle)
  1313. {
  1314. lock (m_deadRegionCache)
  1315. {
  1316. if (m_deadRegionCache.ContainsKey(regionhandle))
  1317. {
  1318. m_deadRegionCache[regionhandle] = m_deadRegionCache[regionhandle] + 1;
  1319. }
  1320. else
  1321. {
  1322. m_deadRegionCache.Add(regionhandle, 1);
  1323. }
  1324. }
  1325. }
  1326. }
  1327. }