HGGridServicesStandalone.cs 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929
  1. /**
  2. * Copyright (c) 2008, Contributors. All rights reserved.
  3. * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4. *
  5. * Redistribution and use in source and binary forms, with or without modification,
  6. * are permitted provided that the following conditions are met:
  7. *
  8. * * Redistributions of source code must retain the above copyright notice,
  9. * this list of conditions and the following disclaimer.
  10. * * Redistributions in binary form must reproduce the above copyright notice,
  11. * this list of conditions and the following disclaimer in the documentation
  12. * and/or other materials provided with the distribution.
  13. * * Neither the name of the Organizations nor the names of Individual
  14. * Contributors may be used to endorse or promote products derived from
  15. * this software without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  18. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
  20. * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  21. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  22. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  23. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  24. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  25. * OF THE POSSIBILITY OF SUCH DAMAGE.
  26. *
  27. */
  28. using System;
  29. using System.Collections;
  30. using System.Collections.Generic;
  31. using System.Net;
  32. using System.Net.Sockets;
  33. using System.Reflection;
  34. using System.Runtime.Remoting;
  35. using System.Runtime.Remoting.Channels;
  36. using System.Runtime.Remoting.Channels.Tcp;
  37. using System.Security.Authentication;
  38. using OpenSim.Framework;
  39. using OpenSim.Framework.Communications;
  40. using OpenSim.Framework.Communications.Cache;
  41. using OpenSim.Framework.Servers;
  42. using OpenSim.Region.Communications.Local;
  43. using OpenSim.Region.Communications.OGS1;
  44. using OpenSim.Region.Environment.Scenes;
  45. using OpenMetaverse;
  46. using Nwc.XmlRpc;
  47. using log4net;
  48. namespace OpenSim.Region.Communications.Hypergrid
  49. {
  50. public class HGGridServicesStandalone : HGGridServices
  51. {
  52. private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  53. /// <summary>
  54. /// Encapsulate local backend services for manipulation of local regions
  55. /// </summary>
  56. protected LocalBackEndServices m_localBackend = new LocalBackEndServices();
  57. private Dictionary<ulong, int> m_deadRegionCache = new Dictionary<ulong, int>();
  58. public LocalBackEndServices LocalBackend
  59. {
  60. get { return m_localBackend; }
  61. }
  62. public override string gdebugRegionName
  63. {
  64. get { return m_localBackend.gdebugRegionName; }
  65. set { m_localBackend.gdebugRegionName = value; }
  66. }
  67. public override bool RegionLoginsEnabled
  68. {
  69. get { return m_localBackend.RegionLoginsEnabled; }
  70. set { m_localBackend.RegionLoginsEnabled = value; }
  71. }
  72. public HGGridServicesStandalone(NetworkServersInfo servers_info, BaseHttpServer httpServe, AssetCache asscache, SceneManager sman)
  73. : base(servers_info, httpServe, asscache, sman)
  74. {
  75. //Respond to Grid Services requests
  76. httpServer.AddXmlRPCHandler("logoff_user", LogOffUser);
  77. httpServer.AddXmlRPCHandler("check", PingCheckReply);
  78. httpServer.AddXmlRPCHandler("land_data", LandData);
  79. StartRemoting();
  80. }
  81. #region IGridServices interface
  82. public override RegionCommsListener RegisterRegion(RegionInfo regionInfo)
  83. {
  84. if (!regionInfo.RegionID.Equals(UUID.Zero))
  85. {
  86. m_regionsOnInstance.Add(regionInfo);
  87. return m_localBackend.RegisterRegion(regionInfo);
  88. }
  89. else
  90. return base.RegisterRegion(regionInfo);
  91. }
  92. public override bool DeregisterRegion(RegionInfo regionInfo)
  93. {
  94. bool success = m_localBackend.DeregisterRegion(regionInfo);
  95. if (!success)
  96. success = base.DeregisterRegion(regionInfo);
  97. return success;
  98. }
  99. public override List<SimpleRegionInfo> RequestNeighbours(uint x, uint y)
  100. {
  101. List<SimpleRegionInfo> neighbours = m_localBackend.RequestNeighbours(x, y);
  102. List<SimpleRegionInfo> remotes = base.RequestNeighbours(x, y);
  103. neighbours.AddRange(remotes);
  104. return neighbours;
  105. }
  106. public override RegionInfo RequestNeighbourInfo(UUID Region_UUID)
  107. {
  108. RegionInfo info = m_localBackend.RequestNeighbourInfo(Region_UUID);
  109. if (info == null)
  110. info = base.RequestNeighbourInfo(Region_UUID);
  111. return info;
  112. }
  113. public override RegionInfo RequestNeighbourInfo(ulong regionHandle)
  114. {
  115. RegionInfo info = m_localBackend.RequestNeighbourInfo(regionHandle);
  116. //m_log.Info("[HGrid] Request neighbor info, local backend returned " + info);
  117. if (info == null)
  118. info = base.RequestNeighbourInfo(regionHandle);
  119. return info;
  120. }
  121. public override RegionInfo RequestClosestRegion(string regionName)
  122. {
  123. RegionInfo info = m_localBackend.RequestClosestRegion(regionName);
  124. if (info == null)
  125. info = base.RequestClosestRegion(regionName);
  126. return info;
  127. }
  128. public override List<MapBlockData> RequestNeighbourMapBlocks(int minX, int minY, int maxX, int maxY)
  129. {
  130. //m_log.Info("[HGrid] Request map blocks " + minX + "-" + minY + "-" + maxX + "-" + maxY);
  131. List<MapBlockData> neighbours = m_localBackend.RequestNeighbourMapBlocks(minX, minY, maxX, maxY);
  132. List<MapBlockData> remotes = base.RequestNeighbourMapBlocks(minX, minY, maxX, maxY);
  133. neighbours.AddRange(remotes);
  134. return neighbours;
  135. }
  136. public override LandData RequestLandData(ulong regionHandle, uint x, uint y)
  137. {
  138. LandData land = m_localBackend.RequestLandData(regionHandle, x, y);
  139. if (land == null)
  140. land = base.RequestLandData(regionHandle, x, y);
  141. return land;
  142. }
  143. public override List<RegionInfo> RequestNamedRegions(string name, int maxNumber)
  144. {
  145. List<RegionInfo> infos = m_localBackend.RequestNamedRegions(name, maxNumber);
  146. List<RegionInfo> remotes = base.RequestNamedRegions(name, maxNumber);
  147. infos.AddRange(remotes);
  148. return infos;
  149. }
  150. #endregion
  151. #region XML Request Handlers
  152. /// <summary>
  153. /// A ping / version check
  154. /// </summary>
  155. /// <param name="request"></param>
  156. /// <returns></returns>
  157. public virtual XmlRpcResponse PingCheckReply(XmlRpcRequest request)
  158. {
  159. XmlRpcResponse response = new XmlRpcResponse();
  160. Hashtable respData = new Hashtable();
  161. respData["online"] = "true";
  162. m_localBackend.PingCheckReply(respData);
  163. response.Value = respData;
  164. return response;
  165. }
  166. // Grid Request Processing
  167. /// <summary>
  168. /// Ooops, our Agent must be dead if we're getting this request!
  169. /// </summary>
  170. /// <param name="request"></param>
  171. /// <returns></returns>
  172. public XmlRpcResponse LogOffUser(XmlRpcRequest request)
  173. {
  174. m_log.Debug("[HGrid]: LogOff User Called");
  175. Hashtable requestData = (Hashtable)request.Params[0];
  176. string message = (string)requestData["message"];
  177. UUID agentID = UUID.Zero;
  178. UUID RegionSecret = UUID.Zero;
  179. UUID.TryParse((string)requestData["agent_id"], out agentID);
  180. UUID.TryParse((string)requestData["region_secret"], out RegionSecret);
  181. ulong regionHandle = Convert.ToUInt64((string)requestData["regionhandle"]);
  182. m_localBackend.TriggerLogOffUser(regionHandle, agentID, RegionSecret, message);
  183. return new XmlRpcResponse();
  184. }
  185. /// <summary>
  186. /// Someone asked us about parcel-information
  187. /// </summary>
  188. /// <param name="request"></param>
  189. /// <returns></returns>
  190. public XmlRpcResponse LandData(XmlRpcRequest request)
  191. {
  192. Hashtable requestData = (Hashtable)request.Params[0];
  193. ulong regionHandle = Convert.ToUInt64(requestData["region_handle"]);
  194. uint x = Convert.ToUInt32(requestData["x"]);
  195. uint y = Convert.ToUInt32(requestData["y"]);
  196. m_log.DebugFormat("[HGrid]: Got XML reqeuest for land data at {0}, {1} in region {2}", x, y, regionHandle);
  197. LandData landData = m_localBackend.RequestLandData(regionHandle, x, y);
  198. Hashtable hash = new Hashtable();
  199. if (landData != null)
  200. {
  201. // for now, only push out the data we need for answering a ParcelInfoReqeust
  202. hash["AABBMax"] = landData.AABBMax.ToString();
  203. hash["AABBMin"] = landData.AABBMin.ToString();
  204. hash["Area"] = landData.Area.ToString();
  205. hash["AuctionID"] = landData.AuctionID.ToString();
  206. hash["Description"] = landData.Description;
  207. hash["Flags"] = landData.Flags.ToString();
  208. hash["GlobalID"] = landData.GlobalID.ToString();
  209. hash["Name"] = landData.Name;
  210. hash["OwnerID"] = landData.OwnerID.ToString();
  211. hash["SalePrice"] = landData.SalePrice.ToString();
  212. hash["SnapshotID"] = landData.SnapshotID.ToString();
  213. hash["UserLocation"] = landData.UserLocation.ToString();
  214. }
  215. XmlRpcResponse response = new XmlRpcResponse();
  216. response.Value = hash;
  217. return response;
  218. }
  219. #endregion
  220. #region Remoting
  221. /// <summary>
  222. /// Start listening for .net remoting calls from other regions.
  223. /// </summary>
  224. private void StartRemoting()
  225. {
  226. m_log.Info("[HGrid]: Start remoting...");
  227. TcpChannel ch;
  228. try
  229. {
  230. ch = new TcpChannel((int)NetworkServersInfo.RemotingListenerPort);
  231. ChannelServices.RegisterChannel(ch, false); // Disabled security as Mono doesn't support this.
  232. }
  233. catch (Exception ex)
  234. {
  235. m_log.Error("[HGrid]: Exception while attempting to listen on TCP port " + (int)NetworkServersInfo.RemotingListenerPort + ".");
  236. throw (ex);
  237. }
  238. WellKnownServiceTypeEntry wellType =
  239. new WellKnownServiceTypeEntry(typeof(OGS1InterRegionRemoting), "InterRegions",
  240. WellKnownObjectMode.Singleton);
  241. RemotingConfiguration.RegisterWellKnownServiceType(wellType);
  242. InterRegionSingleton.Instance.OnArrival += TriggerExpectAvatarCrossing;
  243. InterRegionSingleton.Instance.OnChildAgent += IncomingChildAgent;
  244. InterRegionSingleton.Instance.OnPrimGroupArrival += IncomingPrim;
  245. InterRegionSingleton.Instance.OnPrimGroupNear += TriggerExpectPrimCrossing;
  246. InterRegionSingleton.Instance.OnRegionUp += TriggerRegionUp;
  247. InterRegionSingleton.Instance.OnChildAgentUpdate += TriggerChildAgentUpdate;
  248. InterRegionSingleton.Instance.OnTellRegionToCloseChildConnection += TriggerTellRegionToCloseChildConnection;
  249. }
  250. #endregion
  251. #region IInterRegionCommunications interface (Methods called by regions in this instance)
  252. public override bool ChildAgentUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData)
  253. {
  254. int failures = 0;
  255. lock (m_deadRegionCache)
  256. {
  257. if (m_deadRegionCache.ContainsKey(regionHandle))
  258. {
  259. failures = m_deadRegionCache[regionHandle];
  260. }
  261. }
  262. if (failures <= 3)
  263. {
  264. RegionInfo regInfo = null;
  265. try
  266. {
  267. if (m_localBackend.ChildAgentUpdate(regionHandle, cAgentData))
  268. {
  269. return true;
  270. }
  271. regInfo = RequestNeighbourInfo(regionHandle);
  272. if (regInfo != null)
  273. {
  274. //don't want to be creating a new link to the remote instance every time like we are here
  275. bool retValue = false;
  276. OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject(
  277. typeof(OGS1InterRegionRemoting),
  278. "tcp://" + regInfo.RemotingAddress +
  279. ":" + regInfo.RemotingPort +
  280. "/InterRegions");
  281. if (remObject != null)
  282. {
  283. retValue = remObject.ChildAgentUpdate(regionHandle, cAgentData);
  284. }
  285. else
  286. {
  287. m_log.Warn("[HGrid]: remoting object not found");
  288. }
  289. remObject = null;
  290. return retValue;
  291. }
  292. NoteDeadRegion(regionHandle);
  293. return false;
  294. }
  295. catch (RemotingException e)
  296. {
  297. NoteDeadRegion(regionHandle);
  298. m_log.WarnFormat(
  299. "[HGrid]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}",
  300. regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
  301. m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
  302. return false;
  303. }
  304. catch (SocketException e)
  305. {
  306. NoteDeadRegion(regionHandle);
  307. m_log.WarnFormat(
  308. "[HGrid]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}",
  309. regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
  310. m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
  311. return false;
  312. }
  313. catch (InvalidCredentialException e)
  314. {
  315. NoteDeadRegion(regionHandle);
  316. m_log.WarnFormat(
  317. "[HGrid]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}",
  318. regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
  319. m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
  320. return false;
  321. }
  322. catch (AuthenticationException e)
  323. {
  324. NoteDeadRegion(regionHandle);
  325. m_log.WarnFormat(
  326. "[HGrid]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}",
  327. regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
  328. m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
  329. return false;
  330. }
  331. catch (Exception e)
  332. {
  333. NoteDeadRegion(regionHandle);
  334. m_log.WarnFormat("[HGrid]: Unable to connect to adjacent region: {0} {1},{2}",
  335. regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
  336. m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
  337. return false;
  338. }
  339. }
  340. else
  341. {
  342. //m_log.Info("[INTERREGION]: Skipped Sending Child Update to a region because it failed too many times:" + regionHandle.ToString());
  343. return false;
  344. }
  345. }
  346. /// <summary>
  347. /// Inform a region that a child agent will be on the way from a client.
  348. /// </summary>
  349. /// <param name="regionHandle"></param>
  350. /// <param name="agentData"></param>
  351. /// <returns></returns>
  352. public override bool InformRegionOfChildAgent(ulong regionHandle, AgentCircuitData agentData)
  353. {
  354. if (m_localBackend.InformRegionOfChildAgent(regionHandle, agentData))
  355. {
  356. return true;
  357. }
  358. return base.InformRegionOfChildAgent(regionHandle, agentData);
  359. }
  360. // UGLY!
  361. public override bool RegionUp(SerializableRegionInfo region, ulong regionhandle)
  362. {
  363. if (m_localBackend.RegionUp(region, regionhandle))
  364. return true;
  365. return base.RegionUp(region, regionhandle);
  366. }
  367. /// <summary>
  368. ///
  369. /// </summary>
  370. /// <param name="regionHandle"></param>
  371. /// <param name="agentData"></param>
  372. /// <returns></returns>
  373. public override bool InformRegionOfPrimCrossing(ulong regionHandle, UUID primID, string objData, int XMLMethod)
  374. {
  375. int failures = 0;
  376. lock (m_deadRegionCache)
  377. {
  378. if (m_deadRegionCache.ContainsKey(regionHandle))
  379. {
  380. failures = m_deadRegionCache[regionHandle];
  381. }
  382. }
  383. if (failures <= 1)
  384. {
  385. RegionInfo regInfo = null;
  386. try
  387. {
  388. if (m_localBackend.InformRegionOfPrimCrossing(regionHandle, primID, objData, XMLMethod))
  389. {
  390. return true;
  391. }
  392. regInfo = RequestNeighbourInfo(regionHandle);
  393. if (regInfo != null)
  394. {
  395. //don't want to be creating a new link to the remote instance every time like we are here
  396. bool retValue = false;
  397. OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject(
  398. typeof(OGS1InterRegionRemoting),
  399. "tcp://" + regInfo.RemotingAddress +
  400. ":" + regInfo.RemotingPort +
  401. "/InterRegions");
  402. if (remObject != null)
  403. {
  404. retValue = remObject.InformRegionOfPrimCrossing(regionHandle, primID.Guid, objData, XMLMethod);
  405. }
  406. else
  407. {
  408. m_log.Warn("[HGrid]: Remoting object not found");
  409. }
  410. remObject = null;
  411. return retValue;
  412. }
  413. NoteDeadRegion(regionHandle);
  414. return false;
  415. }
  416. catch (RemotingException e)
  417. {
  418. NoteDeadRegion(regionHandle);
  419. m_log.Warn("[HGrid]: Remoting Error: Unable to connect to adjacent region: " + regionHandle);
  420. m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
  421. return false;
  422. }
  423. catch (SocketException e)
  424. {
  425. NoteDeadRegion(regionHandle);
  426. m_log.Warn("[HGrid]: Remoting Error: Unable to connect to adjacent region: " + regionHandle);
  427. m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
  428. return false;
  429. }
  430. catch (InvalidCredentialException e)
  431. {
  432. NoteDeadRegion(regionHandle);
  433. m_log.Warn("[HGrid]: Invalid Credential Exception: Invalid Credentials : " + regionHandle);
  434. m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
  435. return false;
  436. }
  437. catch (AuthenticationException e)
  438. {
  439. NoteDeadRegion(regionHandle);
  440. m_log.Warn("[HGrid]: Authentication exception: Unable to connect to adjacent region: " + regionHandle);
  441. m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
  442. return false;
  443. }
  444. catch (Exception e)
  445. {
  446. NoteDeadRegion(regionHandle);
  447. m_log.Warn("[HGrid]: Unknown exception: Unable to connect to adjacent region: " + regionHandle);
  448. m_log.DebugFormat("[HGrid]: {0}", e);
  449. return false;
  450. }
  451. }
  452. else
  453. {
  454. return false;
  455. }
  456. }
  457. /// <summary>
  458. ///
  459. /// </summary>
  460. /// <param name="regionHandle"></param>
  461. /// <param name="agentID"></param>
  462. /// <param name="position"></param>
  463. /// <returns></returns>
  464. public override bool ExpectAvatarCrossing(ulong regionHandle, UUID agentID, Vector3 position, bool isFlying)
  465. {
  466. RegionInfo[] regions = m_regionsOnInstance.ToArray();
  467. bool banned = false;
  468. bool localregion = false;
  469. for (int i = 0; i < regions.Length; i++)
  470. {
  471. if (regions[i] != null)
  472. {
  473. if (regions[i].RegionHandle == regionHandle)
  474. {
  475. localregion = true;
  476. if (regions[i].EstateSettings.IsBanned(agentID))
  477. {
  478. banned = true;
  479. break;
  480. }
  481. }
  482. }
  483. }
  484. if (banned)
  485. return false;
  486. if (localregion)
  487. return m_localBackend.ExpectAvatarCrossing(regionHandle, agentID, position, isFlying);
  488. return base.ExpectAvatarCrossing(regionHandle, agentID, position, isFlying);
  489. }
  490. public override bool ExpectPrimCrossing(ulong regionHandle, UUID agentID, Vector3 position, bool isPhysical)
  491. {
  492. RegionInfo regInfo = null;
  493. try
  494. {
  495. if (m_localBackend.TriggerExpectPrimCrossing(regionHandle, agentID, position, isPhysical))
  496. {
  497. return true;
  498. }
  499. regInfo = RequestNeighbourInfo(regionHandle);
  500. if (regInfo != null)
  501. {
  502. bool retValue = false;
  503. OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject(
  504. typeof(OGS1InterRegionRemoting),
  505. "tcp://" + regInfo.RemotingAddress +
  506. ":" + regInfo.RemotingPort +
  507. "/InterRegions");
  508. if (remObject != null)
  509. {
  510. retValue =
  511. remObject.ExpectAvatarCrossing(regionHandle, agentID.Guid, new sLLVector3(position),
  512. isPhysical);
  513. }
  514. else
  515. {
  516. m_log.Warn("[HGrid]: Remoting object not found");
  517. }
  518. remObject = null;
  519. return retValue;
  520. }
  521. //TODO need to see if we know about where this region is and use .net remoting
  522. // to inform it.
  523. NoteDeadRegion(regionHandle);
  524. return false;
  525. }
  526. catch (RemotingException e)
  527. {
  528. NoteDeadRegion(regionHandle);
  529. m_log.Warn("[HGrid]: Remoting Error: Unable to connect to adjacent region: " + regionHandle);
  530. m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
  531. return false;
  532. }
  533. catch (SocketException e)
  534. {
  535. NoteDeadRegion(regionHandle);
  536. m_log.Warn("[HGrid]: Remoting Error: Unable to connect to adjacent region: " + regionHandle);
  537. m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
  538. return false;
  539. }
  540. catch (InvalidCredentialException e)
  541. {
  542. NoteDeadRegion(regionHandle);
  543. m_log.Warn("[HGrid]: Invalid Credential Exception: Invalid Credentials : " + regionHandle);
  544. m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
  545. return false;
  546. }
  547. catch (AuthenticationException e)
  548. {
  549. NoteDeadRegion(regionHandle);
  550. m_log.Warn("[HGrid]: Authentication exception: Unable to connect to adjacent region: " + regionHandle);
  551. m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
  552. return false;
  553. }
  554. catch (Exception e)
  555. {
  556. NoteDeadRegion(regionHandle);
  557. m_log.Warn("[HGrid]: Unknown exception: Unable to connect to adjacent region: " + regionHandle);
  558. m_log.DebugFormat("[HGrid]: {0}", e);
  559. return false;
  560. }
  561. }
  562. public override bool TellRegionToCloseChildConnection(ulong regionHandle, UUID agentID)
  563. {
  564. m_log.Debug("[HGrid]: TellRegion " + regionHandle + " ToCloseChildConnection for " + agentID);
  565. RegionInfo regInfo = null;
  566. try
  567. {
  568. if (m_localBackend.TriggerTellRegionToCloseChildConnection(regionHandle, agentID))
  569. {
  570. return true;
  571. }
  572. regInfo = RequestNeighbourInfo(regionHandle);
  573. if (regInfo != null)
  574. {
  575. // bool retValue = false;
  576. OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject(
  577. typeof(OGS1InterRegionRemoting),
  578. "tcp://" + regInfo.RemotingAddress +
  579. ":" + regInfo.RemotingPort +
  580. "/InterRegions");
  581. if (remObject != null)
  582. {
  583. // retValue =
  584. remObject.TellRegionToCloseChildConnection(regionHandle, agentID.Guid);
  585. }
  586. else
  587. {
  588. m_log.Warn("[HGrid]: Remoting object not found");
  589. }
  590. remObject = null;
  591. return true;
  592. }
  593. //TODO need to see if we know about where this region is and use .net remoting
  594. // to inform it.
  595. NoteDeadRegion(regionHandle);
  596. return false;
  597. }
  598. catch (RemotingException)
  599. {
  600. NoteDeadRegion(regionHandle);
  601. m_log.Warn("[HGrid]: Remoting Error: Unable to connect to adjacent region to tell it to close child agents: " + regInfo.RegionName +
  602. " " + regInfo.RegionLocX + "," + regInfo.RegionLocY);
  603. //m_log.Debug(e.ToString());
  604. return false;
  605. }
  606. catch (SocketException e)
  607. {
  608. NoteDeadRegion(regionHandle);
  609. m_log.Warn("[HGridS]: Socket Error: Unable to connect to adjacent region using tcp://" +
  610. regInfo.RemotingAddress +
  611. ":" + regInfo.RemotingPort +
  612. "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY +
  613. " - Is this neighbor up?");
  614. m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
  615. return false;
  616. }
  617. catch (InvalidCredentialException e)
  618. {
  619. NoteDeadRegion(regionHandle);
  620. m_log.Warn("[HGrid]: Invalid Credentials: Unable to connect to adjacent region using tcp://" +
  621. regInfo.RemotingAddress +
  622. ":" + regInfo.RemotingPort +
  623. "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY);
  624. m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
  625. return false;
  626. }
  627. catch (AuthenticationException e)
  628. {
  629. NoteDeadRegion(regionHandle);
  630. m_log.Warn("[HGrid]: Authentication exception: Unable to connect to adjacent region using tcp://" +
  631. regInfo.RemotingAddress +
  632. ":" + regInfo.RemotingPort +
  633. "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY);
  634. m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
  635. return false;
  636. }
  637. catch (WebException e)
  638. {
  639. NoteDeadRegion(regionHandle);
  640. m_log.Warn("[HGrid]: WebException exception: Unable to connect to adjacent region using tcp://" +
  641. regInfo.RemotingAddress +
  642. ":" + regInfo.RemotingPort +
  643. "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY);
  644. m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
  645. return false;
  646. }
  647. catch (Exception e)
  648. {
  649. NoteDeadRegion(regionHandle);
  650. // This line errors with a Null Reference Exception.. Why? @.@
  651. //m_log.Warn("Unknown exception: Unable to connect to adjacent region using tcp://" + regInfo.RemotingAddress +
  652. // ":" + regInfo.RemotingPort +
  653. //"/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY + " - This is likely caused by an incompatibility in the protocol between this sim and that one");
  654. m_log.DebugFormat("[HGrid]: {0}", e);
  655. return false;
  656. }
  657. }
  658. public override bool AcknowledgeAgentCrossed(ulong regionHandle, UUID agentId)
  659. {
  660. return m_localBackend.AcknowledgeAgentCrossed(regionHandle, agentId);
  661. }
  662. public override bool AcknowledgePrimCrossed(ulong regionHandle, UUID primId)
  663. {
  664. return m_localBackend.AcknowledgePrimCrossed(regionHandle, primId);
  665. }
  666. #endregion
  667. #region Methods triggered by calls from external instances
  668. /// <summary>
  669. ///
  670. /// </summary>
  671. /// <param name="regionHandle"></param>
  672. /// <param name="agentData"></param>
  673. /// <returns></returns>
  674. public bool IncomingChildAgent(ulong regionHandle, AgentCircuitData agentData)
  675. {
  676. HGIncomingChildAgent(regionHandle, agentData);
  677. m_log.Info("[HGrid]: " + gdebugRegionName + ": Incoming HGrid Agent " + agentData.firstname + " " + agentData.lastname);
  678. return m_localBackend.IncomingChildAgent(regionHandle, agentData);
  679. }
  680. public bool TriggerRegionUp(RegionUpData regionData, ulong regionhandle)
  681. {
  682. m_log.Info(
  683. "[HGrid]: " +
  684. m_localBackend._gdebugRegionName + "Incoming HGrid RegionUpReport: " + "(" + regionData.X +
  685. "," + regionData.Y + "). Giving this region a fresh set of 'dead' tries");
  686. RegionInfo nRegionInfo = new RegionInfo();
  687. nRegionInfo.SetEndPoint("127.0.0.1", regionData.PORT);
  688. nRegionInfo.ExternalHostName = regionData.IPADDR;
  689. nRegionInfo.RegionLocX = regionData.X;
  690. nRegionInfo.RegionLocY = regionData.Y;
  691. lock (m_deadRegionCache)
  692. {
  693. if (m_deadRegionCache.ContainsKey(nRegionInfo.RegionHandle))
  694. {
  695. m_deadRegionCache.Remove(nRegionInfo.RegionHandle);
  696. }
  697. }
  698. return m_localBackend.TriggerRegionUp(nRegionInfo, regionhandle);
  699. }
  700. public bool TriggerChildAgentUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData)
  701. {
  702. //m_log.Info("[INTER]: Incoming HGrid Child Agent Data Update");
  703. return m_localBackend.TriggerChildAgentUpdate(regionHandle, cAgentData);
  704. }
  705. /// <summary>
  706. ///
  707. /// </summary>
  708. /// <param name="regionHandle"></param>
  709. /// <param name="agentData"></param>
  710. /// <returns></returns>
  711. public bool IncomingPrim(ulong regionHandle, UUID primID, string objData, int XMLMethod)
  712. {
  713. m_localBackend.TriggerExpectPrim(regionHandle, primID, objData, XMLMethod);
  714. return true;
  715. }
  716. /// <summary>
  717. ///
  718. /// </summary>
  719. /// <param name="regionHandle"></param>
  720. /// <param name="agentID"></param>
  721. /// <param name="position"></param>
  722. /// <returns></returns>
  723. public bool TriggerExpectAvatarCrossing(ulong regionHandle, UUID agentID, Vector3 position, bool isFlying)
  724. {
  725. return m_localBackend.TriggerExpectAvatarCrossing(regionHandle, agentID, position, isFlying);
  726. }
  727. public bool TriggerExpectPrimCrossing(ulong regionHandle, UUID agentID, Vector3 position, bool isPhysical)
  728. {
  729. return m_localBackend.TriggerExpectPrimCrossing(regionHandle, agentID, position, isPhysical);
  730. }
  731. public bool TriggerTellRegionToCloseChildConnection(ulong regionHandle, UUID agentID)
  732. {
  733. return m_localBackend.TriggerTellRegionToCloseChildConnection(regionHandle, agentID);
  734. }
  735. int timeOut = 10; //10 seconds
  736. /// <summary>
  737. /// Check that a region is available for TCP comms. This is necessary for .NET remoting between regions.
  738. /// </summary>
  739. /// <param name="address"></param>
  740. /// <param name="port"></param>
  741. /// <param name="retry"></param>
  742. /// <returns></returns>
  743. public bool CheckRegion(string address, uint port, bool retry)
  744. {
  745. bool available = false;
  746. bool timed_out = true;
  747. IPAddress ia;
  748. IPAddress.TryParse(address, out ia);
  749. IPEndPoint m_EndPoint = new IPEndPoint(ia, (int)port);
  750. AsyncCallback callback = delegate(IAsyncResult iar)
  751. {
  752. Socket s = (Socket)iar.AsyncState;
  753. try
  754. {
  755. s.EndConnect(iar);
  756. available = true;
  757. timed_out = false;
  758. }
  759. catch (Exception e)
  760. {
  761. m_log.DebugFormat(
  762. "[HGrid]: Callback EndConnect exception: {0}:{1}", e.Message, e.StackTrace);
  763. }
  764. s.Close();
  765. };
  766. try
  767. {
  768. Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  769. IAsyncResult ar = socket.BeginConnect(m_EndPoint, callback, socket);
  770. ar.AsyncWaitHandle.WaitOne(timeOut * 1000, false);
  771. }
  772. catch (Exception e)
  773. {
  774. m_log.DebugFormat(
  775. "[HGrid]: CheckRegion Socket Setup exception: {0}:{1}", e.Message, e.StackTrace);
  776. return false;
  777. }
  778. if (timed_out)
  779. {
  780. m_log.DebugFormat(
  781. "[HGrid]: socket [{0}] timed out ({1}) waiting to obtain a connection.",
  782. m_EndPoint, timeOut * 1000);
  783. if (retry)
  784. {
  785. return CheckRegion(address, port, false);
  786. }
  787. }
  788. return available;
  789. }
  790. public override bool CheckRegion(string address, uint port)
  791. {
  792. return CheckRegion(address, port, true);
  793. }
  794. public void NoteDeadRegion(ulong regionhandle)
  795. {
  796. lock (m_deadRegionCache)
  797. {
  798. if (m_deadRegionCache.ContainsKey(regionhandle))
  799. {
  800. m_deadRegionCache[regionhandle] = m_deadRegionCache[regionhandle] + 1;
  801. }
  802. else
  803. {
  804. m_deadRegionCache.Add(regionhandle, 1);
  805. }
  806. }
  807. }
  808. #endregion
  809. }
  810. }