diff -Nur OpenSim-/Framework/NetworkUtil.cs OpenSim/Framework/NetworkUtil.cs --- OpenSim-/Framework/NetworkUtil.cs 2015-03-05 00:50:31.000000000 +0900 +++ OpenSim/Framework/NetworkUtil.cs 2015-03-10 11:48:12.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,101 @@ return defaultHostname; } + + // Fumi.Iseki + public static IPAddress GetIPfromString(string str) + { + IPAddress ip = null; + + if (IPAddress.TryParse(str, out ip)) + { + return ip; + } + + foreach (IPAddress host in Dns.GetHostAddresses(str)) + { + if (host.AddressFamily==AddressFamily.InterNetwork) + { + return host; + } + } + + 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 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/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs --- OpenSim-/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs 2015-03-05 00:50:31.000000000 +0900 +++ OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs 2015-03-10 11:51:07.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 + 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; + 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(agentcaps); + } + } + 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-05 00:50:31.000000000 +0900 +++ OpenSim/Services/Interfaces/IGridService.cs 2015-03-10 11:48:12.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,10 @@ 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==null || InternalIPAddress.ToString()=="0.0.0.0") InternalIPAddress = NetworkUtil.GetIPfromString(ExternalHostName); + // m_log.DebugFormat("{0} New GridRegion. id={1}, loc=<{2},{3}>, size=<{4},{5}>", // LogHeader, RegionID, RegionLocX, RegionLocY, RegionSizeX, RegionSizeY); } @@ -429,6 +440,9 @@ kvp["Token"] = Token.ToString(); // Maturity doesn't seem to exist in the DB + // Fumi.Iseki for NAPT + kvp[m_dbipcolumn] = InternalIPAddress.ToString(); + return kvp; } @@ -519,5 +533,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-05 00:50:31.000000000 +0900 +++ OpenSim/Services/LLLoginService/LLLoginResponse.cs 2015-03-10 11:48:12.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-05 00:50:31.000000000 +0900 +++ OpenSim/Services/LLLoginService/LLLoginService.cs 2015-03-10 11:48:12.000000000 +0900 @@ -448,9 +448,10 @@ } else { + // Fumi.Iseki for NAPT m_log.DebugFormat( - "[LLOGIN SERVICE]: Found destination {0}, endpoint {1} for {2} {3}", - destination.RegionName, destination.ExternalEndPoint, firstName, lastName); + "[LLOGIN SERVICE]: Found destination {0}, endpoint {1}({2}) for {3} {4}", + destination.RegionName, destination.ExternalEndPoint, destination.InternalIPAddress, firstName, lastName); } if (account.UserLevel >= 200)