aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorKunta Kinte2014-04-29 07:26:07 -0700
committerJustin Clark-Casey (justincc)2014-05-06 17:52:32 +0100
commitcecb446e0e91ede0b05ea9cf40c1313782241f3d (patch)
treea94d63639ee46df2ced6d246562fa9cfe42cdf22 /OpenSim/Region
parentFix avatars going to corner of region when they are sitting on a child prim a... (diff)
downloadopensim-SC-cecb446e0e91ede0b05ea9cf40c1313782241f3d.zip
opensim-SC-cecb446e0e91ede0b05ea9cf40c1313782241f3d.tar.gz
opensim-SC-cecb446e0e91ede0b05ea9cf40c1313782241f3d.tar.bz2
opensim-SC-cecb446e0e91ede0b05ea9cf40c1313782241f3d.tar.xz
fix infinite recursion loop in SendGridInstantMessageViaXMLRPCAsync()
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs178
1 files changed, 79 insertions, 99 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
index 40a400f..4f8e2cd 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
@@ -428,7 +428,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
428 /// <summary> 428 /// <summary>
429 /// delegate for sending a grid instant message asynchronously 429 /// delegate for sending a grid instant message asynchronously
430 /// </summary> 430 /// </summary>
431 public delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID); 431 public delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result);
432 432
433 protected virtual void GridInstantMessageCompleted(IAsyncResult iar) 433 protected virtual void GridInstantMessageCompleted(IAsyncResult iar)
434 { 434 {
@@ -442,138 +442,118 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
442 { 442 {
443 GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsync; 443 GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsync;
444 444
445 d.BeginInvoke(im, result, UUID.Zero, GridInstantMessageCompleted, d); 445 d.BeginInvoke(im, result, GridInstantMessageCompleted, d);
446 } 446 }
447 447
448 /// <summary> 448 /// <summary>
449 /// Recursive SendGridInstantMessage over XMLRPC method. 449 /// Internal SendGridInstantMessage over XMLRPC method.
450 /// This is called from within a dedicated thread. 450 /// This is called from within a dedicated thread.
451 /// The first time this is called, prevRegionHandle will be 0 Subsequent times this is called from
452 /// itself, prevRegionHandle will be the last region handle that we tried to send.
453 /// If the handles are the same, we look up the user's location using the grid.
454 /// If the handles are still the same, we end. The send failed.
455 /// </summary> 451 /// </summary>
456 /// <param name="prevRegionHandle"> 452 private void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result)
457 /// Pass in 0 the first time this method is called. It will be called recursively with the last
458 /// regionhandle tried
459 /// </param>
460 protected virtual void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID)
461 { 453 {
462 UUID toAgentID = new UUID(im.toAgentID); 454 UUID toAgentID = new UUID(im.toAgentID);
455 UUID regionID;
456 bool lookupAgent;
463 457
464 PresenceInfo upd = null; 458 /*
465 459 * Try to get what region the agent is in from the cache.
466 bool lookupAgent = false; 460 */
467
468 lock (m_UserRegionMap) 461 lock (m_UserRegionMap)
469 { 462 {
470 if (m_UserRegionMap.ContainsKey(toAgentID)) 463 lookupAgent = !m_UserRegionMap.TryGetValue(toAgentID, out regionID);
471 {
472 upd = new PresenceInfo();
473 upd.RegionID = m_UserRegionMap[toAgentID];
474
475 // We need to compare the current regionhandle with the previous region handle
476 // or the recursive loop will never end because it will never try to lookup the agent again
477 if (prevRegionID == upd.RegionID)
478 {
479 lookupAgent = true;
480 }
481 }
482 else
483 {
484 lookupAgent = true;
485 }
486 } 464 }
487
488 465
489 // Are we needing to look-up an agent? 466 while (true)
490 if (lookupAgent)
491 { 467 {
492 // Non-cached user agent lookup. 468
493 PresenceInfo[] presences = PresenceService.GetAgents(new string[] { toAgentID.ToString() }); 469 /*
494 if (presences != null && presences.Length > 0) 470 * If not in cache, try to find out what region the agent is in.
471 * Also do this if we know the existing cache entry is bad.
472 */
473 if (lookupAgent)
495 { 474 {
496 foreach (PresenceInfo p in presences) 475 PresenceInfo[] presences = PresenceService.GetAgents(new string[] { toAgentID.ToString() });
476
477 regionID = UUID.Zero;
478 if (presences != null)
497 { 479 {
498 if (p.RegionID != UUID.Zero) 480 foreach (PresenceInfo p in presences)
499 { 481 {
500 upd = p; 482 if (p.RegionID != UUID.Zero)
501 break; 483 {
484 regionID = p.RegionID;
485 break;
486 }
502 } 487 }
503 } 488 }
504 }
505 489
506 if (upd != null) 490 // If not found, message is undeliverable
507 { 491 if (regionID == UUID.Zero)
508 // check if we've tried this before..
509 // This is one way to end the recursive loop
510 //
511 if (upd.RegionID == prevRegionID)
512 { 492 {
513 // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message"); 493 break;
514 HandleUndeliveredMessage(im, result);
515 return;
516 } 494 }
517 } 495 }
518 else 496
497 /*
498 * Try to find out about region.
499 * If unable, message is undeliverable.
500 */
501 GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, regionID);
502 if (reginfo == null)
519 { 503 {
520 // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message"); 504 m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find region {0}", regionID);
521 HandleUndeliveredMessage(im, result); 505 break;
522 return;
523 } 506 }
524 }
525 507
526 if (upd != null) 508 /*
527 { 509 * Try to send message to agent in the region.
528 GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, 510 */
529 upd.RegionID); 511 Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(im);
530 if (reginfo != null) 512 msgdata["region_handle"] = 0;
513 bool imresult = doIMSending(reginfo, msgdata);
514
515 /*
516 * If message delivery successful, save cache entry because we know it is good.
517 * Then tell caller message has been delivered and we are done.
518 */
519 if (imresult)
531 { 520 {
532 Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(im); 521 lock (m_UserRegionMap)
533 // Not actually used anymore, left in for compatibility
534 // Remove at next interface change
535 //
536 msgdata["region_handle"] = 0;
537 bool imresult = doIMSending(reginfo, msgdata);
538 if (imresult)
539 {
540 // IM delivery successful, so store the Agent's location in our local cache.
541 lock (m_UserRegionMap)
542 {
543 if (m_UserRegionMap.ContainsKey(toAgentID))
544 {
545 m_UserRegionMap[toAgentID] = upd.RegionID;
546 }
547 else
548 {
549 m_UserRegionMap.Add(toAgentID, upd.RegionID);
550 }
551 }
552 result(true);
553 }
554 else
555 { 522 {
556 // try again, but lookup user this time. 523 m_UserRegionMap[toAgentID] = regionID;
557 // Warning, this must call the Async version
558 // of this method or we'll be making thousands of threads
559 // The version within the spawned thread is SendGridInstantMessageViaXMLRPCAsync
560 // The version that spawns the thread is SendGridInstantMessageViaXMLRPC
561
562 // This is recursive!!!!!
563 SendGridInstantMessageViaXMLRPCAsync(im, result,
564 upd.RegionID);
565 } 524 }
525 result(true);
526 return;
566 } 527 }
567 else 528
529 /*
530 * Message delivery failed.
531 * If we just looked up what region the agent is in, message is undeliverable.
532 */
533 if (lookupAgent)
568 { 534 {
569 m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find region {0}", upd.RegionID); 535 break;
570 HandleUndeliveredMessage(im, result);
571 } 536 }
537
538 /*
539 * We used a cached entry that we now know is bad.
540 * Try again by searching the grid for the user.
541 */
542 lookupAgent = true;
572 } 543 }
573 else 544
545 /*
546 * Message is undeliverable for one reason or another.
547 * Remove possible bad entry from cache.
548 * Then inform caller that the message is undeliverable.
549 */
550 lock (m_UserRegionMap)
574 { 551 {
575 HandleUndeliveredMessage(im, result); 552 m_UserRegionMap.Remove(toAgentID);
576 } 553 }
554
555 // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
556 HandleUndeliveredMessage(im, result);
577 } 557 }
578 558
579 /// <summary> 559 /// <summary>