diff -Nur OpenSim-/Capabilities/Caps.cs OpenSim/Capabilities/Caps.cs --- OpenSim-/Capabilities/Caps.cs 2015-03-04 23:01:03.000000000 +0900 +++ OpenSim/Capabilities/Caps.cs 2015-03-11 22:35:52.000000000 +0900 @@ -82,9 +82,11 @@ get { return m_regionName; } } + // Fumi.Iseki for NAPT public string HostName { get { return m_httpListenerHostName; } + set { m_httpListenerHostName = value; } } public uint Port diff -Nur OpenSim-/Framework/NetworkUtil.cs OpenSim/Framework/NetworkUtil.cs --- OpenSim-/Framework/NetworkUtil.cs 2015-03-04 23:01:03.000000000 +0900 +++ OpenSim/Framework/NetworkUtil.cs 2015-03-12 01:25:17.000000000 +0900 @@ -60,6 +60,9 @@ // IPv4Address, Subnet static readonly Dictionary m_subnets = new Dictionary(); + // IPv4 Private Address // Fumi.Iseki + static readonly Dictionary m_private = new Dictionary(); + public static IPAddress GetIPFor(IPAddress user, IPAddress simulator) { if (m_disabled) @@ -191,9 +194,17 @@ { if (address.Address.AddressFamily == AddressFamily.InterNetwork) { - if (address.IPv4Mask != null) + // Fumi.Iseki for mono + try + { + if (address.IPv4Mask != null) + { + m_subnets.Add(address.Address, address.IPv4Mask); + } + } + catch (NotImplementedException) { - m_subnets.Add(address.Address, address.IPv4Mask); + m_subnets.Add(address.Address, IPAddress.Parse("255.255.255.0")); } } } @@ -203,6 +214,11 @@ { // Mono Sucks. } + + // Fumi.Iseki + m_private.Add(IPAddress.Parse("10.0.0.0"), IPAddress.Parse("255.0.0.0")); + m_private.Add(IPAddress.Parse("172.16.0.0"), IPAddress.Parse("255.240.0.0")); + m_private.Add(IPAddress.Parse("192.168.0.0"), IPAddress.Parse("255.255.0.0")); } public static IPAddress GetIPFor(IPEndPoint user, string defaultHostname) @@ -246,5 +262,123 @@ return defaultHostname; } + + // Fumi.Iseki + public static IPAddress GetIPfromString(string str) + { + IPAddress ip = null; + + if (str=="") + { + ip = IPAddress.Parse("0.0.0.0"); + return ip; + } + + if (IPAddress.TryParse(str, out ip)) + { + return ip; + } + + try + { + foreach (IPAddress host in Dns.GetHostAddresses(str)) + { + if (host.AddressFamily==AddressFamily.InterNetwork) + { + return host; + } + } + } + catch (System.Net.Sockets.SocketException) + { + ip = IPAddress.Parse("0.0.0.0"); + } + + return ip; + } + + + // Fumi.Iseki + public static IPAddress GetEffectiveIP(IPAddress viewer, IPAddress internalIP, IPAddress externalIP, IPAddress myExternalIP) + { + if (internalIP.Equals(externalIP)) return externalIP; // Target is outside of NAPT + + if (viewer.Equals(externalIP)) // Target is local with viewer + { + m_log.Info("[NetworkUtil.GetEffectiveIP] Local LAN[0] user detected, sending them '" + internalIP.ToString() + "'"); + return internalIP; + } + + if (IsInternalSubnet(viewer)) // Viewer is inside + { + if (myExternalIP!=null && !myExternalIP.Equals(externalIP)) // Target is outside + { + m_log.Info("[NetworkUtil.GetEffectiveIP] Remote LAN[0] user detected, sending them '" + externalIP.ToString() + "'"); + return externalIP; + } + m_log.Info("[NetworkUtil.GetEffectiveIP] Local LAN[1] user detected, sending them '" + internalIP.ToString() + "'"); + return internalIP; + } + + m_log.Info("[NetworkUtil.GetEffectiveIP] Remote LAN[1] user detected, sending them '" + externalIP.ToString() + "'"); + return externalIP; + } + + + // Fumi.Iseki + public static bool IsInternalSubnet(IPAddress address) + { + // Same as own IP + foreach (IPAddress host in Dns.GetHostAddresses(Dns.GetHostName())) + { + if (host.Equals(address) && host.AddressFamily==AddressFamily.InterNetwork) return true; + } + + if (IsSameNetwork(address, m_subnets)) return true; + if (IsSameNetwork(address, m_private)) return true; + + return false; + } + + + // Fumi.Iseki + public static bool IsPrivateSubnet(IPAddress address) + { + if (IsSameNetwork(address, m_private)) return true; + + return false; + } + + + // Fumi.Iseki + public static bool IsSameNetwork(IPAddress address, Dictionary subnets) + { + // Check for same LAN segment + byte[] destBytes = address.GetAddressBytes(); + + foreach (KeyValuePair subnet in subnets) + { + if (subnet.Key.AddressFamily != AddressFamily.InterNetwork) continue; + + byte[] subnetBytes = subnet.Value.GetAddressBytes(); + byte[] localBytes = subnet.Key.GetAddressBytes(); + + if (subnetBytes.Length!=destBytes.Length || subnetBytes.Length!=localBytes.Length) continue; + + bool samenet = true; + for (int i=0; i /// The x co-ordinate of this region in map tiles (e.g. 1000). /// Coordinate is scaled as world coordinates divided by the legacy region size @@ -647,6 +658,7 @@ address = IPAddress.Parse(MainConsole.Instance.CmdPrompt("Internal IP address", "0.0.0.0")); config.Set("InternalAddress", address.ToString()); } + m_internalIPAddress = address; // Fumi.Iseki for NAPT // InternalPort // @@ -702,6 +714,9 @@ m_externalHostName = externalName; } + // Fumi.Iseki for NAPT + if (m_internalIPAddress.ToString()=="0.0.0.0") m_internalIPAddress = NetworkUtil.GetIPfromString(m_externalHostName); + // RegionType m_regionType = config.GetString("RegionType", String.Empty); allKeys.Remove("RegionType"); @@ -912,6 +927,7 @@ if ((RegionName != null) && !RegionName.Equals("")) args["region_name"] = OSD.FromString(RegionName); args["external_host_name"] = OSD.FromString(ExternalHostName); + args["internal_ip_address"] = OSD.FromString(InternalIPAddress.ToString()); // Fumi.Iseki for NAPT args["http_port"] = OSD.FromString(HttpPort.ToString()); args["server_uri"] = OSD.FromString(ServerURI); @@ -943,6 +959,8 @@ RegionName = args["region_name"].AsString(); if (args["external_host_name"] != null) ExternalHostName = args["external_host_name"].AsString(); + if (args["internal_ip_address"] != null) + InternalIPAddress = IPAddress.Parse(args["internal_ip_address"].AsString()); // Fumi.Iseki for NAPT if (args["http_port"] != null) UInt32.TryParse(args["http_port"].AsString(), out m_httpPort); if (args["server_uri"] != null) @@ -989,11 +1007,14 @@ m_regionType = args["region_type"].AsString(); } - public static RegionInfo Create(UUID regionID, string regionName, uint regX, uint regY, string externalHostName, uint httpPort, uint simPort, uint remotingPort, string serverURI) + // Fumi.Iseki for NAPT + //public static RegionInfo Create(UUID regionID, string regionName, uint regX, uint regY, string externalHostName, uint httpPort, uint simPort, uint remotingPort, string serverURI) + public static RegionInfo Create(UUID regionID, string regionName, uint regX, uint regY, string externalHostName, IPAddress internalIP, uint httpPort, uint simPort, uint remotingPort, string serverURI) { RegionInfo regionInfo; IPEndPoint neighbourInternalEndPoint = new IPEndPoint(Util.GetHostFromDNS(externalHostName), (int)simPort); - regionInfo = new RegionInfo(regX, regY, neighbourInternalEndPoint, externalHostName); + //regionInfo = new RegionInfo(regX, regY, neighbourInternalEndPoint, externalHostName); + regionInfo = new RegionInfo(regX, regY, neighbourInternalEndPoint, externalHostName, internalIP); regionInfo.RemotingPort = remotingPort; regionInfo.RemotingAddress = externalHostName; regionInfo.HttpPort = httpPort; diff -Nur OpenSim-/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs --- OpenSim-/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs 2015-03-04 23:01:03.000000000 +0900 +++ OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs 2015-03-11 22:35:52.000000000 +0900 @@ -280,6 +280,12 @@ public void RegisterCaps(UUID agentID, Caps caps) { + // Fumi.Iseki for NAPT + // see MakeAgent() in OpenSim/Services/LLLoginService/LLLoginService.cs + string channel = m_scene.AuthenticateHandler.GetAgentCircuitData(agentID).Channel; + if (channel.Contains(" [Internal]")) caps.HostName = m_scene.RegionInfo.InternalIPAddress.ToString(); + + UploadBakedTextureHandler avatarhandler = new UploadBakedTextureHandler( caps, m_scene.AssetService, m_persistBakedTextures); diff -Nur OpenSim-/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs --- OpenSim-/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs 2015-03-04 23:01:03.000000000 +0900 +++ OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs 2015-03-11 22:35:52.000000000 +0900 @@ -141,7 +141,21 @@ // "[CAPS]: Adding capabilities for agent {0} in {1} with path {2}", // agentId, m_scene.RegionInfo.RegionName, capsObjectPath); - caps = new Caps(MainServer.Instance, m_scene.RegionInfo.ExternalHostName, + // Fumi.Iseki for NAPT + string hostName = m_scene.RegionInfo.ExternalHostName; + IClientAPI client = null; + if (m_scene.TryGetClient(agentId, out client)) + { + if (NetworkUtil.IsInternalSubnet(client.RemoteEndPoint.Address)) hostName = m_scene.RegionInfo.InternalIPAddress.ToString(); + } + else + { + // see MakeAgent() in OpenSim/Services/LLLoginService/LLLoginService.cs + string channel = m_scene.AuthenticateHandler.GetAgentCircuitData(agentId).Channel; + if (channel.Contains(" [Internal]")) hostName = m_scene.RegionInfo.InternalIPAddress.ToString(); + } + //caps = new Caps(MainServer.Instance, m_scene.RegionInfo.ExternalHostName, + caps = new Caps(MainServer.Instance, hostName, (MainServer.Instance == null) ? 0: MainServer.Instance.Port, capsObjectPath, agentId, m_scene.RegionInfo.RegionName); diff -Nur OpenSim-/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs --- OpenSim-/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs 2015-03-04 23:01:03.000000000 +0900 +++ OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs 2015-03-11 22:35:52.000000000 +0900 @@ -746,6 +746,19 @@ // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, // it's actually doing a lot of work. IPEndPoint endPoint = finalDestination.ExternalEndPoint; + + // Fumi.Iseki for NAPT + uint circuitCode = sp.ControllingClient.CircuitCode; + IPAddress clientAddress = NetworkUtil.GetIPfromString(sp.Scene.AuthenticateHandler.GetAgentCircuitData(circuitCode).IPAddress); + if (clientAddress!=null) + { + IPAddress intrnlAddress = finalDestination.InternalIPAddress; + IPAddress extrnlAddress = finalDestination.ExternalEndPoint.Address; + IPAddress regionAddress = sourceRegion.ExternalEndPoint.Address; + IPAddress effectAddress = NetworkUtil.GetEffectiveIP(clientAddress, intrnlAddress, extrnlAddress, regionAddress); + endPoint = new IPEndPoint(effectAddress, finalDestination.ExternalEndPoint.Port); + } + if (endPoint == null || endPoint.Address == null) { sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); @@ -888,6 +901,23 @@ return; } + // Fumi.Iseki + string serverURI = finalDestination.ServerURI; + uint circuitCode = sp.ControllingClient.CircuitCode; + IPAddress clientAddress = NetworkUtil.GetIPfromString(sp.Scene.AuthenticateHandler.GetAgentCircuitData(circuitCode).IPAddress); + if (clientAddress!=null) + { + IPAddress intrnlAddress = finalDestination.InternalIPAddress; + IPAddress extrnlAddress = finalDestination.ExternalEndPoint.Address; + if (!extrnlAddress.Equals(intrnlAddress)) + { + IPAddress regionAddress = sp.Scene.RegionInfo.ExternalEndPoint.Address; + IPAddress effectAddress = NetworkUtil.GetEffectiveIP(clientAddress, intrnlAddress, extrnlAddress, regionAddress); + string host = serverURI.Split(new char[] { '/', ':' })[3]; + serverURI = serverURI.Replace(host, effectAddress.ToString()); + } + } + // Past this point we have to attempt clean up if the teleport fails, so update transfer state. m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); @@ -905,14 +935,16 @@ finalDestination.RegionName, newRegionX, newRegionY, sp.Name, Scene.Name); //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent..."); - #region IP Translation for NAT + // Fumi.Iseki for NAPT + //#region IP Translation for NAT // Uses ipepClient above - if (sp.ClientView.TryGet(out ipepClient)) - { - endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); - } - #endregion - capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); + //if (sp.ClientView.TryGet(out ipepClient)) + //{ + // endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); + //} + //#endregion + //capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); + capsPath = serverURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); if (m_eqModule != null) { @@ -946,7 +978,8 @@ else { agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle); - capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); + //capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); + capsPath = serverURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); } // Let's send a full update of the agent. This is a synchronous call. @@ -1139,6 +1172,23 @@ return; } + // Fumi.Iseki + string serverURI = finalDestination.ServerURI; + uint circuitCode = sp.ControllingClient.CircuitCode; + IPAddress clientAddress = NetworkUtil.GetIPfromString(sp.Scene.AuthenticateHandler.GetAgentCircuitData(circuitCode).IPAddress); + if (clientAddress!=null) + { + IPAddress intrnlAddress = finalDestination.InternalIPAddress; + IPAddress extrnlAddress = finalDestination.ExternalEndPoint.Address; + if (!extrnlAddress.Equals(intrnlAddress)) + { + IPAddress regionAddress = sp.Scene.RegionInfo.ExternalEndPoint.Address; + IPAddress effectAddress = NetworkUtil.GetEffectiveIP(clientAddress, intrnlAddress, extrnlAddress, regionAddress); + string host = serverURI.Split(new char[] { '/', ':' })[3]; + serverURI = serverURI.Replace(host, effectAddress.ToString()); + } + } + // Past this point we have to attempt clean up if the teleport fails, so update transfer state. m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); @@ -1153,19 +1203,22 @@ finalDestination.RegionName, newRegionX, newRegionY, sp.Name, Scene.Name); //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent..."); - #region IP Translation for NAT + // Fumi.Iseki for NAPT + //#region IP Translation for NAT // Uses ipepClient above - if (sp.ClientView.TryGet(out ipepClient)) - { - endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); - } - #endregion - capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); + //if (sp.ClientView.TryGet(out ipepClient)) + //{ + // endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); + //} + //#endregion + //capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); + capsPath = serverURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); } else { agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle); - capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); + //capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); + capsPath = serverURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); } // We need to set this here to avoid an unlikely race condition when teleporting to a neighbour simulator, @@ -1338,6 +1391,23 @@ { agent.CallbackURI = region.ServerURI + "agent/" + agent.AgentID.ToString() + "/" + region.RegionID.ToString() + "/release/"; + // Fumi.Iseki for NAPT + uint circuitCode = agent.CircuitCode; + IPAddress clientAddress = NetworkUtil.GetIPfromString(Scene.AuthenticateHandler.GetAgentCircuitData(circuitCode).IPAddress); + if (clientAddress!=null) + { + IPAddress intrnlAddress = region.InternalIPAddress; + IPAddress extrnlAddress = region.ExternalEndPoint.Address; + if (!extrnlAddress.Equals(intrnlAddress)) + { + IPAddress regionAddress = Scene.RegionInfo.ExternalEndPoint.Address; + IPAddress effectAddress = NetworkUtil.GetEffectiveIP(clientAddress, intrnlAddress, extrnlAddress, regionAddress); + string host = region.ServerURI.Split(new char[] { '/', ':' })[3]; + string suri = region.ServerURI.Replace(host, effectAddress.ToString()); + agent.CallbackURI = suri + "agent/" + agent.AgentID.ToString() + "/" + region.RegionID.ToString() + "/release/"; + } + } + m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Set release callback URL to {0} in {1}", agent.CallbackURI, region.RegionName); @@ -1753,22 +1823,49 @@ string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); + // Fumi.Iseki + IPAddress effectAddress = null; + string serverURI = neighbourRegion.ServerURI; + uint circuitCode = agent.ControllingClient.CircuitCode; + IPAddress clientAddress = NetworkUtil.GetIPfromString(agent.Scene.AuthenticateHandler.GetAgentCircuitData(circuitCode).IPAddress); + if (clientAddress!=null) + { + IPAddress intrnlAddress = neighbourRegion.InternalIPAddress; + IPAddress extrnlAddress = neighbourRegion.ExternalEndPoint.Address; + if (!extrnlAddress.Equals(intrnlAddress)) + { + IPAddress regionAddress = agent.Scene.RegionInfo.ExternalEndPoint.Address; + effectAddress = NetworkUtil.GetEffectiveIP(clientAddress, intrnlAddress, extrnlAddress, regionAddress); + string host = serverURI.Split(new char[] { '/', ':' })[3]; + serverURI = serverURI.Replace(host, effectAddress.ToString()); + capsPath = serverURI + CapsUtil.GetCapsSeedPath(agentcaps); + } + } + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0); + // Fumi.Iseki for NAPT + IPEndPoint endPoint = neighbourRegion.ExternalEndPoint; + if (effectAddress!=null) + { + endPoint = new IPEndPoint(effectAddress, neighbourRegion.ExternalEndPoint.Port); + } if (m_eqModule != null) { m_eqModule.CrossRegion( neighbourRegion.RegionHandle, pos + agent.Velocity, vel2 /* agent.Velocity */, - neighbourRegion.ExternalEndPoint, + //neighbourRegion.ExternalEndPoint, + endPoint, capsPath, agent.UUID, agent.ControllingClient.SessionId, neighbourRegion.RegionSizeX, neighbourRegion.RegionSizeY); } else { m_log.ErrorFormat("{0} Using old CrossRegion packet. Varregion will not work!!", LogHeader); - agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos + agent.Velocity, agent.Velocity, neighbourRegion.ExternalEndPoint, + //agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos + agent.Velocity, agent.Velocity, neighbourRegion.ExternalEndPoint, + agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos + agent.Velocity, agent.Velocity, endPoint, capsPath); } @@ -1898,6 +1995,19 @@ } IPEndPoint external = region.ExternalEndPoint; + + // Fumi.Iseki for NAPT + uint circuitCode = sp.ControllingClient.CircuitCode; + IPAddress clientAddress = NetworkUtil.GetIPfromString(sp.Scene.AuthenticateHandler.GetAgentCircuitData(circuitCode).IPAddress); + if (clientAddress!=null) + { + IPAddress intrnlAddress = region.InternalIPAddress; + IPAddress extrnlAddress = region.ExternalEndPoint.Address; + IPAddress regionAddress = sp.Scene.RegionInfo.ExternalEndPoint.Address; + IPAddress effectAddress = NetworkUtil.GetEffectiveIP(clientAddress, intrnlAddress, extrnlAddress, regionAddress); + external = new IPEndPoint(effectAddress, region.ExternalEndPoint.Port); + } + if (external != null) { InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; @@ -2021,6 +2131,11 @@ //avatar.Scene.DumpChildrenSeeds(avatar.UUID); //avatar.DumpKnownRegions(); + // Fumi.Iseki for NAPT + uint circuitCode = sp.ControllingClient.CircuitCode; + IPAddress clientAddress = NetworkUtil.GetIPfromString(sp.Scene.AuthenticateHandler.GetAgentCircuitData(circuitCode).IPAddress); + IPAddress regionAddress = sp.Scene.RegionInfo.ExternalEndPoint.Address; + bool newAgent = false; int count = 0; foreach (GridRegion neighbour in neighbours) @@ -2040,11 +2155,21 @@ // Let's put this back at sync, so that it doesn't clog // the network, especially for regions in the same physical server. // We're really not in a hurry here. - InformClientOfNeighbourAsync(sp, cagents[count], neighbour, neighbour.ExternalEndPoint, newAgent); + //InformClientOfNeighbourAsync(sp, cagents[count], neighbour, neighbour.ExternalEndPoint, newAgent); //InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; //d.BeginInvoke(sp, cagents[count], neighbour, neighbour.ExternalEndPoint, newAgent, // InformClientOfNeighbourCompleted, // d); + // Fumi.Iseki for NAPT + IPEndPoint endPoint = neighbour.ExternalEndPoint; + if (clientAddress!=null) + { + IPAddress intrnlAddress = neighbour.InternalIPAddress; + IPAddress extrnlAddress = neighbour.ExternalEndPoint.Address; + IPAddress effectAddress = NetworkUtil.GetEffectiveIP(clientAddress, intrnlAddress, extrnlAddress, regionAddress); + endPoint = new IPEndPoint(effectAddress, neighbour.ExternalEndPoint.Port); + } + InformClientOfNeighbourAsync(sp, cagents[count], neighbour, endPoint, newAgent); } catch (ArgumentOutOfRangeException) @@ -2301,6 +2426,24 @@ string capsPath = reg.ServerURI + CapsUtil.GetCapsSeedPath(a.CapsPath); + // Fumi.Iseki + string serverURI = reg.ServerURI; + uint circuitCode = sp.ControllingClient.CircuitCode; + IPAddress clientAddress = NetworkUtil.GetIPfromString(sp.Scene.AuthenticateHandler.GetAgentCircuitData(circuitCode).IPAddress); + if (clientAddress!=null) + { + IPAddress intrnlAddress = reg.InternalIPAddress; + IPAddress extrnlAddress = reg.ExternalEndPoint.Address; + if (!extrnlAddress.Equals(intrnlAddress)) + { + IPAddress regionAddress = sp.Scene.RegionInfo.ExternalEndPoint.Address; + IPAddress effectAddress = NetworkUtil.GetEffectiveIP(clientAddress, intrnlAddress, extrnlAddress, regionAddress); + string host = serverURI.Split(new char[] { '/', ':' })[3]; + serverURI = serverURI.Replace(host, effectAddress.ToString()); + capsPath = serverURI + CapsUtil.GetCapsSeedPath(a.CapsPath); + } + } + string reason = String.Empty; bool regionAccepted = scene.SimulationService.CreateAgent(null, reg, a, (uint)TeleportFlags.Default, out reason); @@ -2309,13 +2452,14 @@ { if (m_eqModule != null) { - #region IP Translation for NAT - IClientIPEndpoint ipepClient; - if (sp.ClientView.TryGet(out ipepClient)) - { - endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); - } - #endregion + // Fumi.Iseki for NAPT + //#region IP Translation for NAT + //IClientIPEndpoint ipepClient; + //if (sp.ClientView.TryGet(out ipepClient)) + //{ + // endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); + //} + //#endregion m_log.DebugFormat("{0} {1} is sending {2} EnableSimulator for neighbour region {3}(loc=<{4},{5}>,siz=<{6},{7}>) " + "and EstablishAgentCommunication with seed cap {8}", LogHeader, diff -Nur OpenSim-/Services/Interfaces/IGridService.cs OpenSim/Services/Interfaces/IGridService.cs --- OpenSim-/Services/Interfaces/IGridService.cs 2015-03-04 23:01:04.000000000 +0900 +++ OpenSim/Services/Interfaces/IGridService.cs 2015-03-12 08:00:55.000000000 +0900 @@ -194,6 +194,8 @@ protected IPEndPoint m_internalEndPoint; + protected IPAddress m_internalIPAddress = null; // Fumi.Iseki for NAPT + /// /// The co-ordinate of this region in region units. /// @@ -296,6 +298,7 @@ RegionSizeY = (int)ConvertFrom.RegionSizeY; m_internalEndPoint = ConvertFrom.InternalEndPoint; m_externalHostName = ConvertFrom.ExternalHostName; + m_internalIPAddress = ConvertFrom.InternalIPAddress; // Fumi.Iseki for NAPT HttpPort = ConvertFrom.HttpPort; RegionID = ConvertFrom.RegionID; ServerURI = ConvertFrom.ServerURI; @@ -317,6 +320,7 @@ RegionSizeY = ConvertFrom.RegionSizeY; m_internalEndPoint = ConvertFrom.InternalEndPoint; m_externalHostName = ConvertFrom.ExternalHostName; + m_internalIPAddress = ConvertFrom.InternalIPAddress; // Fumi.Iseki for NAPT HttpPort = ConvertFrom.HttpPort; RegionID = ConvertFrom.RegionID; ServerURI = ConvertFrom.ServerURI; @@ -328,6 +332,9 @@ EstateOwner = ConvertFrom.EstateOwner; } + // Fumi.Iseki for NAPT + private string m_dbipcolumn = "Token"; + public GridRegion(Dictionary kvp) { if (kvp.ContainsKey("uuid")) @@ -400,6 +407,13 @@ if (kvp.ContainsKey("Token")) Token = kvp["Token"].ToString(); + // Fumi.Iseki for NAPT + if (kvp.ContainsKey(m_dbipcolumn)) + { + InternalIPAddress = NetworkUtil.GetIPfromString(kvp[m_dbipcolumn].ToString()); + if (InternalIPAddress.ToString()=="0.0.0.0") InternalIPAddress = ExternalEndPoint.Address; + } + // m_log.DebugFormat("{0} New GridRegion. id={1}, loc=<{2},{3}>, size=<{4},{5}>", // LogHeader, RegionID, RegionLocX, RegionLocY, RegionSizeX, RegionSizeY); } @@ -429,6 +443,9 @@ kvp["Token"] = Token.ToString(); // Maturity doesn't seem to exist in the DB + // Fumi.Iseki for NAPT [if Robust server, comment out this] + if (NetworkUtil.IsPrivateSubnet(InternalIPAddress)) kvp[m_dbipcolumn] = InternalIPAddress.ToString(); + return kvp; } @@ -519,5 +536,20 @@ { get { return Util.UIntsToLong((uint)RegionLocX, (uint)RegionLocY); } } + + + // Fumi.Iseki for NAPT + public IPAddress InternalIPAddress + { + get { + if (m_internalIPAddress==null) { + m_internalIPAddress = m_internalEndPoint.Address; + if (m_internalIPAddress.ToString()=="0.0.0.0") m_internalIPAddress = ExternalEndPoint.Address; + } + return m_internalIPAddress; + } + set { m_internalIPAddress = value; } + } + } -} \ No newline at end of file +} diff -Nur OpenSim-/Services/LLLoginService/LLLoginResponse.cs OpenSim/Services/LLLoginService/LLLoginResponse.cs --- OpenSim-/Services/LLLoginService/LLLoginResponse.cs 2015-03-04 23:01:04.000000000 +0900 +++ OpenSim/Services/LLLoginService/LLLoginResponse.cs 2015-03-11 22:35:52.000000000 +0900 @@ -257,7 +257,8 @@ FillOutHomeData(pinfo, home); LookAt = String.Format("[r{0},r{1},r{2}]", lookAt.X, lookAt.Y, lookAt.Z); - FillOutRegionData(destination); + //FillOutRegionData(destination); + FillOutRegionData(destination, clientIP); // Fumi.Iseki for NAPT m_log.DebugFormat("[LOGIN RESPONSE] LLLoginResponse create. sizeX={0}, sizeY={1}", RegionSizeX, RegionSizeY); FillOutSeedCap(aCircuit, destination, clientIP); @@ -378,10 +379,16 @@ } - private void FillOutRegionData(GridRegion destination) + // Fumi.Iseki for NAPT + //private void FillOutRegionData(GridRegion destination) + private void FillOutRegionData(GridRegion destination, IPEndPoint clientIP) { IPEndPoint endPoint = destination.ExternalEndPoint; - SimAddress = endPoint.Address.ToString(); + //SimAddress = endPoint.Address.ToString(); + IPAddress extAddress = NetworkUtil.GetIPfromString(destination.ExternalHostName); + IPAddress simAddress = NetworkUtil.GetEffectiveIP(clientIP.Address, destination.InternalIPAddress, extAddress, null); + SimAddress = simAddress.ToString(); + // SimPort = (uint)endPoint.Port; RegionX = (uint)destination.RegionLocX; RegionY = (uint)destination.RegionLocY; @@ -392,6 +399,16 @@ private void FillOutSeedCap(AgentCircuitData aCircuit, GridRegion destination, IPEndPoint ipepClient) { SeedCapability = destination.ServerURI + CapsUtil.GetCapsSeedPath(aCircuit.CapsPath); + // Fumi.Iseki for NAPT + IPAddress extAddress = NetworkUtil.GetIPfromString(destination.ExternalHostName); + if (!extAddress.Equals(destination.InternalIPAddress)) + { + IPAddress simip = NetworkUtil.GetEffectiveIP(ipepClient.Address, destination.InternalIPAddress, extAddress, null); + string uri = destination.ServerURI; + string host = uri.Split(new char[] { '/', ':' })[3]; + uri = uri.Replace(host, simip.ToString()); + SeedCapability = uri + CapsUtil.GetCapsSeedPath(aCircuit.CapsPath); + } } private void SetDefaultValues() diff -Nur OpenSim-/Services/LLLoginService/LLLoginService.cs OpenSim/Services/LLLoginService/LLLoginService.cs --- OpenSim-/Services/LLLoginService/LLLoginService.cs 2015-03-04 23:01:04.000000000 +0900 +++ OpenSim/Services/LLLoginService/LLLoginService.cs 2015-03-11 22:35:52.000000000 +0900 @@ -900,6 +900,13 @@ aCircuit.Id0 = id0; SetServiceURLs(aCircuit, account); + // Fumi.Iseki for NAPT + if (region.ExternalEndPoint.Address.ToString()==ipaddress) + { + //aCircuit.Channel += " [IP:" + region.InternalIPAddress.ToString() + "]"; + aCircuit.Channel += " [Internal]"; + m_log.DebugFormat("[LLLOGIN SERVICE]: set [Internal] to AgentCircuitData.Channel: {0}", aCircuit.Channel); + } return aCircuit; }