aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
diff options
context:
space:
mode:
authorDiva Canto2013-07-22 11:54:35 -0700
committerDiva Canto2013-07-24 14:27:58 -0700
commit3891a8946bb72c9256d8de4185bf4a72c90be859 (patch)
tree3c4e2ca2468c287e1c0ea711ad6808bef0d82449 /OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
parentFurther tweaks on TPs: not sending the callback URL and instead waiting 15sec... (diff)
downloadopensim-SC-3891a8946bb72c9256d8de4185bf4a72c90be859.zip
opensim-SC-3891a8946bb72c9256d8de4185bf4a72c90be859.tar.gz
opensim-SC-3891a8946bb72c9256d8de4185bf4a72c90be859.tar.bz2
opensim-SC-3891a8946bb72c9256d8de4185bf4a72c90be859.tar.xz
New Teleport protocol (V2), still compatible with V1 and older. (version of the destination is being checked)
In this new protocol, and as committed before, the viewer is not sent EnableSimulator/EstablishChildCommunication for the destination. Instead, it is sent TeleportFinish directly. TeleportFinish, in turn, makes the viewer send a UserCircuitCode packet followed by CompleteMovementIntoRegion packet. These 2 packets tend to occur one after the other almost immediately to the point that when CMIR arrives the client is not even connected yet and that packet is ignored (there might have been some race conditions here before); then the viewer sends CMIR again within 5-8 secs. But the delay between them may be higher in busier regions, which may lead to race conditions. This commit improves the process so there are are no race conditions at the destination. CompleteMovement (triggered by the viewer) waits until Update has been sent from the origin. Update, in turn, waits until there is a *root* scene presence -- so making sure CompleteMovement has run MakeRoot. In other words, there are two threadlets at the destination, one from the viewer and one from the origin region, waiting for each other to do the right thing. That makes it safe to close the agent at the origin upon return of the Update call without having to wait for callback, because we are absolutely sure that the viewer knows it is in th new region. Note also that in the V1 protocol, the destination was getting UseCircuitCode from the viewer twice -- once on EstablishAgentCommunication and then again on TeleportFinish. The second UCC was being ignored, but it shows how we were not following the expected steps...
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs68
1 files changed, 68 insertions, 0 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 37fd252..1b72b26 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -1257,6 +1257,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1257 // UseCircuitCode handling 1257 // UseCircuitCode handling
1258 if (packet.Type == PacketType.UseCircuitCode) 1258 if (packet.Type == PacketType.UseCircuitCode)
1259 { 1259 {
1260 m_log.DebugFormat("[ZZZ]: In the dungeon: UseCircuitCode");
1260 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the 1261 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the
1261 // buffer. 1262 // buffer.
1262 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; 1263 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
@@ -1265,6 +1266,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1265 1266
1266 return; 1267 return;
1267 } 1268 }
1269 else if (packet.Type == PacketType.CompleteAgentMovement)
1270 {
1271 // Send ack straight away to let the viewer know that we got it.
1272 SendAckImmediate(endPoint, packet.Header.Sequence);
1273
1274 m_log.DebugFormat("[ZZZ]: In the dungeon: CompleteAgentMovement");
1275 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the
1276 // buffer.
1277 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
1278
1279 Util.FireAndForget(HandleCompleteMovementIntoRegion, array);
1280
1281 return;
1282 }
1268 1283
1269 // Determine which agent this packet came from 1284 // Determine which agent this packet came from
1270 IClientAPI client; 1285 IClientAPI client;
@@ -1604,6 +1619,56 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1604 } 1619 }
1605 } 1620 }
1606 1621
1622 private void HandleCompleteMovementIntoRegion(object o)
1623 {
1624 IPEndPoint endPoint = null;
1625 IClientAPI client = null;
1626
1627 try
1628 {
1629 object[] array = (object[])o;
1630 endPoint = (IPEndPoint)array[0];
1631 CompleteAgentMovementPacket packet = (CompleteAgentMovementPacket)array[1];
1632
1633 // Determine which agent this packet came from
1634 int count = 10;
1635 while (!m_scene.TryGetClient(endPoint, out client) && count-- > 0)
1636 {
1637 m_log.Debug("[LLUDPSERVER]: Received a CompleteMovementIntoRegion in " + m_scene.RegionInfo.RegionName + " (not ready yet)");
1638 Thread.Sleep(200);
1639 }
1640
1641 if (client == null)
1642 return;
1643
1644 IncomingPacket incomingPacket1;
1645
1646 // Inbox insertion
1647 if (UsePools)
1648 {
1649 incomingPacket1 = m_incomingPacketPool.GetObject();
1650 incomingPacket1.Client = (LLClientView)client;
1651 incomingPacket1.Packet = packet;
1652 }
1653 else
1654 {
1655 incomingPacket1 = new IncomingPacket((LLClientView)client, packet);
1656 }
1657
1658 packetInbox.Enqueue(incomingPacket1);
1659 }
1660 catch (Exception e)
1661 {
1662 m_log.ErrorFormat(
1663 "[LLUDPSERVER]: CompleteMovementIntoRegion handling from endpoint {0}, client {1} {2} failed. Exception {3}{4}",
1664 endPoint != null ? endPoint.ToString() : "n/a",
1665 client != null ? client.Name : "unknown",
1666 client != null ? client.AgentId.ToString() : "unknown",
1667 e.Message,
1668 e.StackTrace);
1669 }
1670 }
1671
1607 /// <summary> 1672 /// <summary>
1608 /// Send an ack immediately to the given endpoint. 1673 /// Send an ack immediately to the given endpoint.
1609 /// </summary> 1674 /// </summary>
@@ -1999,6 +2064,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1999 Packet packet = incomingPacket.Packet; 2064 Packet packet = incomingPacket.Packet;
2000 LLClientView client = incomingPacket.Client; 2065 LLClientView client = incomingPacket.Client;
2001 2066
2067 if (packet is CompleteAgentMovementPacket)
2068 m_log.DebugFormat("[ZZZ]: Received CompleteAgentMovementPacket");
2069
2002 if (client.IsActive) 2070 if (client.IsActive)
2003 { 2071 {
2004 m_currentIncomingClient = client; 2072 m_currentIncomingClient = client;