Changed the way HG client verification is done: now transforming local and LAN client IPs into external IPs. This addresses some issues related to running both the user agents service and the viewer in the same machine/LAN, which then presents a problem when the user agent goes to an external network.

prebuild-update
Diva Canto 2010-07-30 14:04:13 -07:00
parent b83910f12a
commit 8ab7d80b09
4 changed files with 84 additions and 9 deletions

View File

@ -31,6 +31,7 @@ using System.Net.Sockets;
using System.Net;
using System.Net.NetworkInformation;
using System.Reflection;
using System.Text;
using log4net;
namespace OpenSim.Framework
@ -180,10 +181,14 @@ namespace OpenSim.Framework
throw new ArgumentException("[NetworkUtil] Unable to resolve defaultHostname to an IPv4 address for an IPv4 client");
}
static IPAddress externalIPAddress;
static NetworkUtil()
{
try
{
externalIPAddress = GetExternalIP();
foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
{
foreach (UnicastIPAddressInformation address in ni.GetIPProperties().UnicastAddresses)
@ -244,5 +249,72 @@ namespace OpenSim.Framework
}
return defaultHostname;
}
public static IPAddress GetExternalIPOf(IPAddress user)
{
// Check if we're accessing localhost.
foreach (IPAddress host in Dns.GetHostAddresses(Dns.GetHostName()))
{
if (host.Equals(user) && host.AddressFamily == AddressFamily.InterNetwork)
{
m_log.Info("[NetworkUtil] Localhost user detected, sending '" + externalIPAddress + "' instead of '" + user + "'");
return externalIPAddress;
}
}
// Check for same LAN segment
foreach (KeyValuePair<IPAddress, IPAddress> 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 user;
bool valid = true;
for (int i = 0; i < subnetBytes.Length; i++)
{
if ((localBytes[i] & subnetBytes[i]) != (destBytes[i] & subnetBytes[i]))
{
valid = false;
break;
}
}
if (subnet.Key.AddressFamily != AddressFamily.InterNetwork)
valid = false;
if (valid)
{
m_log.Info("[NetworkUtil] Local LAN user detected, sending '" + externalIPAddress + "' instead of '" + user + "'");
return externalIPAddress;
}
}
// Otherwise, return user address
return user;
}
private static IPAddress GetExternalIP()
{
string whatIsMyIp = "http://www.whatismyip.com/automation/n09230945.asp";
WebClient wc = new WebClient();
UTF8Encoding utf8 = new UTF8Encoding();
string requestHtml = "";
try
{
requestHtml = utf8.GetString(wc.DownloadData(whatIsMyIp));
}
catch (WebException we)
{
// do something with exception
m_log.Info("[NetworkUtil]: Exception in GetExternalIP: " + we.ToString());
}
IPAddress externalIp = IPAddress.Parse(requestHtml);
return externalIp;
}
}
}

View File

@ -2725,7 +2725,9 @@ namespace OpenSim.Region.Framework.Scenes
IUserAgentVerificationModule userVerification = RequestModuleInterface<IUserAgentVerificationModule>();
if (userVerification != null && ep != null)
{
if (!userVerification.VerifyClient(aCircuit, ep.Address.ToString()))
System.Net.IPAddress addr = NetworkUtil.GetExternalIPOf(ep.Address);
if (!userVerification.VerifyClient(aCircuit, /*ep.Address.ToString() */ addr.ToString()))
{
// uh-oh, this is fishy
m_log.DebugFormat("[Scene]: User Client Verification for {0} {1} in {2} returned false", aCircuit.firstname, aCircuit.lastname, RegionInfo.RegionName);

View File

@ -63,6 +63,8 @@ namespace OpenSim.Services.HypergridService
protected static IGridService m_GridService;
protected static GatekeeperServiceConnector m_GatekeeperConnector;
protected static bool m_BypassClientVerification;
public UserAgentService(IConfigSource config)
{
if (!m_Initialized)
@ -76,6 +78,8 @@ namespace OpenSim.Services.HypergridService
string gridService = serverConfig.GetString("GridService", String.Empty);
string gridUserService = serverConfig.GetString("GridUserService", String.Empty);
m_BypassClientVerification = serverConfig.GetBoolean("BypassClientVerification", false);
if (gridService == string.Empty || gridUserService == string.Empty)
throw new Exception(String.Format("Incomplete specifications, UserAgent Service cannot function."));
@ -212,11 +216,10 @@ namespace OpenSim.Services.HypergridService
public bool VerifyClient(UUID sessionID, string token)
{
m_log.DebugFormat("[USER AGENT SERVICE]: Verifying Client session {0} with token {1}", sessionID, token);
//return true;
if (m_BypassClientVerification)
return true;
// Commenting this for now until I understand better what part of a sender's
// info stays unchanged throughout a session
m_log.DebugFormat("[USER AGENT SERVICE]: Verifying Client session {0} with token {1}", sessionID, token);
if (m_TravelingAgents.ContainsKey(sessionID))
return m_TravelingAgents[sessionID].ClientToken == token;

View File

@ -754,10 +754,8 @@ namespace OpenSim.Services.LLLoginService
m_log.Debug("[LLOGIN SERVICE] Launching agent at " + destination.RegionName);
if (m_UserAgentService.LoginAgentToGrid(aCircuit, gatekeeper, destination, out reason))
{
// We may need to do this at some point,
// so leaving it here in comments.
//IPAddress addr = NetworkUtil.GetIPFor(clientIP.Address, destination.ExternalEndPoint.Address);
m_UserAgentService.SetClientToken(aCircuit.SessionID, /*addr.Address.ToString() */ clientIP.Address.ToString());
IPAddress addr = NetworkUtil.GetExternalIPOf(clientIP.Address);
m_UserAgentService.SetClientToken(aCircuit.SessionID, addr.ToString() /* clientIP.Address.ToString() */);
return true;
}
return false;