From 3b1b3ac9bbd77796a55bcc75d08f78bff5ca78af Mon Sep 17 00:00:00 2001 From: Adam Frisby Date: Sat, 23 May 2009 05:44:18 +0000 Subject: [PATCH] * Breaks OpenSim.. err I mean.. adds NAT translation support to EnableSimulator EventQueue methods. * NB: This may actually break logins on certain regions. Shake well before consuming. --- OpenSim/Framework/NetworkUtil.cs | 40 ++++++++++++++++++- .../Hypergrid/HGSceneCommunicationService.cs | 9 +++++ .../Scenes/SceneCommunicationService.cs | 17 ++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/OpenSim/Framework/NetworkUtil.cs b/OpenSim/Framework/NetworkUtil.cs index 759c52f8d2..81e6cadfd6 100644 --- a/OpenSim/Framework/NetworkUtil.cs +++ b/OpenSim/Framework/NetworkUtil.cs @@ -14,11 +14,49 @@ namespace OpenSim.Framework /// This enables standard port forwarding techniques /// to work correctly with OpenSim. /// - static class NetworkUtil + public static class NetworkUtil { // IPv4Address, Subnet static readonly Dictionary m_subnets = new Dictionary(); + public static IPAddress GetIPFor(IPAddress user, IPAddress simulator) + { + // Check if we're accessing localhost. + foreach (IPAddress host in Dns.GetHostAddresses(Dns.GetHostName())) + { + if (host.Equals(user) && host.AddressFamily == AddressFamily.InterNetwork) + return host; + } + + // Check for same LAN segment + foreach (KeyValuePair subnet in m_subnets) + { + byte[] subnetBytes = subnet.Value.GetAddressBytes(); + byte[] localBytes = subnet.Key.GetAddressBytes(); + byte[] destBytes = user.GetAddressBytes(); + + if (subnetBytes.Length != destBytes.Length || subnetBytes.Length != localBytes.Length) + return null; + + bool valid = true; + + for (int i = 0; i < subnetBytes.Length; i++) + { + if ((localBytes[i] & subnetBytes[i]) != (destBytes[i] & subnetBytes[i])) + { + valid = false; + break; + } + } + + if (valid) + return subnet.Key; + } + + // Otherwise, return outside address + return simulator; + } + private static IPAddress GetExternalIPFor(IPAddress destination, string defaultHostname) { // Adds IPv6 Support (Not that any of the major protocols supports it...) diff --git a/OpenSim/Region/Framework/Scenes/Hypergrid/HGSceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/Hypergrid/HGSceneCommunicationService.cs index 542e7d0ea2..7d55cc837f 100644 --- a/OpenSim/Region/Framework/Scenes/Hypergrid/HGSceneCommunicationService.cs +++ b/OpenSim/Region/Framework/Scenes/Hypergrid/HGSceneCommunicationService.cs @@ -33,6 +33,7 @@ using System.Threading; using log4net; using OpenMetaverse; using OpenSim.Framework; +using OpenSim.Framework.Client; using OpenSim.Framework.Communications; using OpenSim.Framework.Communications.Cache; using OpenSim.Framework.Communications.Capabilities; @@ -211,6 +212,14 @@ namespace OpenSim.Region.Framework.Scenes.Hypergrid if (eq != null) { + #region IP Translation for NAT + IClientIPEndpoint ipepClient; + if (avatar.ClientView.TryGet(out ipepClient)) + { + endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); + } + #endregion + eq.EnableSimulator(realHandle, endPoint, avatar.UUID); // ES makes the client send a UseCircuitCode message to the destination, diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs index 0699552c49..85a3d96e5d 100644 --- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs @@ -34,6 +34,7 @@ using OpenMetaverse; using OpenMetaverse.StructuredData; using log4net; using OpenSim.Framework; +using OpenSim.Framework.Client; using OpenSim.Framework.Communications; using OpenSim.Framework.Communications.Cache; using OpenSim.Framework.Communications.Capabilities; @@ -306,6 +307,14 @@ namespace OpenSim.Region.Framework.Scenes IEventQueue eq = avatar.Scene.RequestModuleInterface(); if (eq != null) { + #region IP Translation for NAT + IClientIPEndpoint ipepClient; + if(avatar.ClientView.TryGet(out ipepClient)) + { + endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); + } + #endregion + eq.EnableSimulator(reg.RegionHandle, endPoint, avatar.UUID); eq.EstablishAgentCommunication(avatar.UUID, endPoint, capsPath); m_log.DebugFormat("[CAPS]: Sending new CAPS seed url {0} to client {1} in region {2}", @@ -812,6 +821,14 @@ namespace OpenSim.Region.Framework.Scenes if (eq != null) { + #region IP Translation for NAT + IClientIPEndpoint ipepClient; + if (avatar.ClientView.TryGet(out ipepClient)) + { + endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); + } + #endregion + eq.EnableSimulator(reg.RegionHandle, endPoint, avatar.UUID); // ES makes the client send a UseCircuitCode message to the destination,