Core/Network: Refactor local/remote ip address selection code and allow using hostnames in LoginREST bnetserver config options

Port From (https://github.com/TrinityCore/TrinityCore/commit/6be536a73bc8a6e331ce20e7d19e2ea56b99b4d0)
This commit is contained in:
hondacrx
2023-08-28 11:15:57 -04:00
parent 0e3b271db3
commit c9ab9e4635
7 changed files with 49 additions and 51 deletions
@@ -18,17 +18,15 @@ namespace BNetServer
{ {
public class LoginServiceManager : Singleton<LoginServiceManager> public class LoginServiceManager : Singleton<LoginServiceManager>
{ {
ConcurrentDictionary<(uint ServiceHash, uint MethodId), BnetServiceHandler> serviceHandlers; ConcurrentDictionary<(uint ServiceHash, uint MethodId), BnetServiceHandler> serviceHandlers = new();
FormInputs formInputs; FormInputs formInputs = new();
IPEndPoint externalAddress; string _externalHostname;
IPEndPoint localAddress; IPEndPoint _externalEndpoint;
string _localHostname;
IPEndPoint _localEndpoint;
X509Certificate2 certificate; X509Certificate2 certificate;
LoginServiceManager() LoginServiceManager() { }
{
serviceHandlers = new ConcurrentDictionary<(uint ServiceHash, uint MethodId), BnetServiceHandler>();
formInputs = new FormInputs();
}
public void Initialize() public void Initialize()
{ {
@@ -46,7 +44,9 @@ namespace BNetServer
Log.outError(LogFilter.Network, $"Could not resolve LoginREST.ExternalAddress {configuredAddress}"); Log.outError(LogFilter.Network, $"Could not resolve LoginREST.ExternalAddress {configuredAddress}");
return; return;
} }
externalAddress = new IPEndPoint(address, port);
_externalEndpoint = new IPEndPoint(address, port);
_externalHostname = $"{configuredAddress}:{port}";
configuredAddress = ConfigMgr.GetDefaultValue("LoginREST.LocalAddress", "127.0.0.1"); configuredAddress = ConfigMgr.GetDefaultValue("LoginREST.LocalAddress", "127.0.0.1");
if (!IPAddress.TryParse(configuredAddress, out address)) if (!IPAddress.TryParse(configuredAddress, out address))
@@ -55,7 +55,8 @@ namespace BNetServer
return; return;
} }
localAddress = new IPEndPoint(address, port); _localEndpoint = new IPEndPoint(address, port);
_localHostname = $"{configuredAddress}:{port}";
// set up form inputs // set up form inputs
formInputs.Type = "LOGIN_FORM"; formInputs.Type = "LOGIN_FORM";
@@ -117,14 +118,22 @@ namespace BNetServer
return serviceHandlers.LookupByKey((serviceHash, methodId)); return serviceHandlers.LookupByKey((serviceHash, methodId));
} }
public IPEndPoint GetAddressForClient(IPAddress address) public IPEndPoint GetEndpointForClient(IPAddress address)
{ {
if (IPAddress.IsLoopback(address)) if (IPAddress.IsLoopback(address))
return localAddress; return _localEndpoint;
return externalAddress; return _externalEndpoint;
} }
public string GetHostnameForClient(IPEndPoint address)
{
if (IPAddress.IsLoopback(address.Address))
return _localHostname;
return _externalHostname;
}
public FormInputs GetFormInput() public FormInputs GetFormInput()
{ {
return formInputs; return formInputs;
@@ -39,11 +39,11 @@ namespace BNetServer.Networking
os = logonRequest.Platform; os = logonRequest.Platform;
build = (uint)logonRequest.ApplicationVersion; build = (uint)logonRequest.ApplicationVersion;
var endpoint = Global.LoginServiceMgr.GetAddressForClient(GetRemoteIpEndPoint().Address); var hostname = Global.LoginServiceMgr.GetHostnameForClient(GetRemoteIpEndPoint());
ChallengeExternalRequest externalChallenge = new(); ChallengeExternalRequest externalChallenge = new();
externalChallenge.PayloadType = "web_auth_url"; externalChallenge.PayloadType = "web_auth_url";
externalChallenge.Payload = ByteString.CopyFromUtf8($"https://{endpoint.Address}:{endpoint.Port}/bnetserver/login/"); externalChallenge.Payload = ByteString.CopyFromUtf8($"https://{hostname}/bnetserver/login/");
SendRequest((uint)OriginalHash.ChallengeListener, 3, externalChallenge); SendRequest((uint)OriginalHash.ChallengeListener, 3, externalChallenge);
return BattlenetRpcErrorCode.Ok; return BattlenetRpcErrorCode.Ok;
+2 -2
View File
@@ -37,10 +37,10 @@ namespace Framework.Database
fileName = @"/sql/base/characters_database.sql"; fileName = @"/sql/base/characters_database.sql";
break; break;
case "WorldDatabase": case "WorldDatabase":
fileName = @"/sql/TDB_full_world_1007.23041_2023_04_02.sql"; fileName = @"/sql/TDB_full_world_1015.23071_2023_07_14.sql";
break; break;
case "HotfixDatabase": case "HotfixDatabase":
fileName = @"/sql/TDB_full_hotfixes_1007.23041_2023_04_02.sql"; fileName = @"/sql/TDB_full_hotfixes_1015.23071_2023_07_14.sql";
break; break;
} }
@@ -10,7 +10,7 @@ namespace Framework.Database
const string BnetAccountInfo = "ba.id, ba.email, ba.locked, ba.lock_country, ba.last_ip, ba.LoginTicketExpiry, bab.unbandate > UNIX_TIMESTAMP() OR bab.unbandate = bab.bandate, bab.unbandate = bab.bandate"; const string BnetAccountInfo = "ba.id, ba.email, ba.locked, ba.lock_country, ba.last_ip, ba.LoginTicketExpiry, bab.unbandate > UNIX_TIMESTAMP() OR bab.unbandate = bab.bandate, bab.unbandate = bab.bandate";
const string BnetGameAccountInfo = "a.id, a.username, ab.unbandate, ab.unbandate = ab.bandate, aa.SecurityLevel"; const string BnetGameAccountInfo = "a.id, a.username, ab.unbandate, ab.unbandate = ab.bandate, aa.SecurityLevel";
PrepareStatement(LoginStatements.SEL_REALMLIST, "SELECT id, name, address, localAddress, localSubnetMask, port, icon, flag, timezone, allowedSecurityLevel, population, gamebuild, Region, Battlegroup FROM realmlist WHERE flag <> 3 ORDER BY name"); PrepareStatement(LoginStatements.SEL_REALMLIST, "SELECT id, name, address, localAddress, port, icon, flag, timezone, allowedSecurityLevel, population, gamebuild, Region, Battlegroup FROM realmlist WHERE flag <> 3 ORDER BY name");
PrepareStatement(LoginStatements.DelExpiredIpBans, "DELETE FROM ip_banned WHERE unbandate<>bandate AND unbandate<=UNIX_TIMESTAMP()"); PrepareStatement(LoginStatements.DelExpiredIpBans, "DELETE FROM ip_banned WHERE unbandate<>bandate AND unbandate<=UNIX_TIMESTAMP()");
PrepareStatement(LoginStatements.UpdExpiredAccountBans, "UPDATE account_banned SET active = 0 WHERE active = 1 AND unbandate<>bandate AND unbandate<=UNIX_TIMESTAMP()"); PrepareStatement(LoginStatements.UpdExpiredAccountBans, "UPDATE account_banned SET active = 0 WHERE active = 1 AND unbandate<>bandate AND unbandate<=UNIX_TIMESTAMP()");
PrepareStatement(LoginStatements.SelIpInfo, "SELECT unbandate > UNIX_TIMESTAMP() OR unbandate = bandate AS banned, NULL as country FROM ip_banned WHERE ip = ?"); PrepareStatement(LoginStatements.SelIpInfo, "SELECT unbandate > UNIX_TIMESTAMP() OR unbandate = bandate AS banned, NULL as country FROM ip_banned WHERE ip = ?");
+2 -11
View File
@@ -18,7 +18,7 @@ public class Realm : IEquatable<Realm>
public IPEndPoint GetAddressForClient(IPAddress clientAddr) public IPEndPoint GetAddressForClient(IPAddress clientAddr)
{ {
IPAddress realmIp; IPAddress realmIp = ExternalAddress;
// Attempt to send best address for client // Attempt to send best address for client
if (IPAddress.IsLoopback(clientAddr)) if (IPAddress.IsLoopback(clientAddr))
@@ -33,13 +33,6 @@ public class Realm : IEquatable<Realm>
realmIp = LocalAddress; realmIp = LocalAddress;
} }
} }
else
{
if (clientAddr.AddressFamily == AddressFamily.InterNetwork && clientAddr.GetNetworkAddress(LocalSubnetMask).Equals(LocalAddress.GetNetworkAddress(LocalSubnetMask)))
realmIp = LocalAddress;
else
realmIp = ExternalAddress;
}
IPEndPoint endpoint = new(realmIp, Port); IPEndPoint endpoint = new(realmIp, Port);
@@ -66,7 +59,6 @@ public class Realm : IEquatable<Realm>
{ {
return other.ExternalAddress.Equals(ExternalAddress) return other.ExternalAddress.Equals(ExternalAddress)
&& other.LocalAddress.Equals(LocalAddress) && other.LocalAddress.Equals(LocalAddress)
&& other.LocalSubnetMask.Equals(LocalSubnetMask)
&& other.Port == Port && other.Port == Port
&& other.Name == Name && other.Name == Name
&& other.Type == Type && other.Type == Type
@@ -78,14 +70,13 @@ public class Realm : IEquatable<Realm>
public override int GetHashCode() public override int GetHashCode()
{ {
return new { ExternalAddress, LocalAddress, LocalSubnetMask, Port, Name, Type, Flags, Timezone, AllowedSecurityLevel, PopulationLevel }.GetHashCode(); return new { ExternalAddress, LocalAddress, Port, Name, Type, Flags, Timezone, AllowedSecurityLevel, PopulationLevel }.GetHashCode();
} }
public RealmId Id; public RealmId Id;
public uint Build; public uint Build;
public IPAddress ExternalAddress; public IPAddress ExternalAddress;
public IPAddress LocalAddress; public IPAddress LocalAddress;
public IPAddress LocalSubnetMask;
public ushort Port; public ushort Port;
public string Name; public string Name;
public string NormalizedName; public string NormalizedName;
+9 -10
View File
@@ -94,23 +94,22 @@ public class RealmManager : Singleton<RealmManager>
realm.Name = result.Read<string>(1); realm.Name = result.Read<string>(1);
realm.ExternalAddress = IPAddress.Parse(result.Read<string>(2)); realm.ExternalAddress = IPAddress.Parse(result.Read<string>(2));
realm.LocalAddress = IPAddress.Parse(result.Read<string>(3)); realm.LocalAddress = IPAddress.Parse(result.Read<string>(3));
realm.LocalSubnetMask = IPAddress.Parse(result.Read<string>(4)); realm.Port = result.Read<ushort>(4);
realm.Port = result.Read<ushort>(5); RealmType realmType = (RealmType)result.Read<byte>(5);
RealmType realmType = (RealmType)result.Read<byte>(6);
if (realmType == RealmType.FFAPVP) if (realmType == RealmType.FFAPVP)
realmType = RealmType.PVP; realmType = RealmType.PVP;
if (realmType >= RealmType.MaxType) if (realmType >= RealmType.MaxType)
realmType = RealmType.Normal; realmType = RealmType.Normal;
realm.Type = (byte)realmType; realm.Type = (byte)realmType;
realm.Flags = (RealmFlags)result.Read<byte>(7); realm.Flags = (RealmFlags)result.Read<byte>(6);
realm.Timezone = result.Read<byte>(8); realm.Timezone = result.Read<byte>(7);
AccountTypes allowedSecurityLevel = (AccountTypes)result.Read<byte>(9); AccountTypes allowedSecurityLevel = (AccountTypes)result.Read<byte>(8);
realm.AllowedSecurityLevel = (allowedSecurityLevel <= AccountTypes.Administrator ? allowedSecurityLevel : AccountTypes.Administrator); realm.AllowedSecurityLevel = (allowedSecurityLevel <= AccountTypes.Administrator ? allowedSecurityLevel : AccountTypes.Administrator);
realm.PopulationLevel = result.Read<float>(10); realm.PopulationLevel = result.Read<float>(9);
realm.Build = result.Read<uint>(11); realm.Build = result.Read<uint>(10);
byte region = result.Read<byte>(12); byte region = result.Read<byte>(11);
byte battlegroup = result.Read<byte>(13); byte battlegroup = result.Read<byte>(12);
realm.Id = new RealmId(region, battlegroup, realmId); realm.Id = new RealmId(region, battlegroup, realmId);
+10 -11
View File
@@ -2438,23 +2438,22 @@ namespace Game
public bool LoadRealmInfo() public bool LoadRealmInfo()
{ {
SQLResult result = DB.Login.Query("SELECT id, name, address, localAddress, localSubnetMask, port, icon, flag, timezone, allowedSecurityLevel, population, gamebuild, Region, Battlegroup FROM realmlist WHERE id = {0}", _realm.Id.Index); SQLResult result = DB.Login.Query("SELECT id, name, address, localAddress, port, icon, flag, timezone, allowedSecurityLevel, population, gamebuild, Region, Battlegroup FROM realmlist WHERE id = {0}", _realm.Id.Index);
if (result.IsEmpty()) if (result.IsEmpty())
return false; return false;
_realm.SetName(result.Read<string>(1)); _realm.SetName(result.Read<string>(1));
_realm.ExternalAddress = System.Net.IPAddress.Parse(result.Read<string>(2)); _realm.ExternalAddress = System.Net.IPAddress.Parse(result.Read<string>(2));
_realm.LocalAddress = System.Net.IPAddress.Parse(result.Read<string>(3)); _realm.LocalAddress = System.Net.IPAddress.Parse(result.Read<string>(3));
_realm.LocalSubnetMask = System.Net.IPAddress.Parse(result.Read<string>(4)); _realm.Port = result.Read<ushort>(4);
_realm.Port = result.Read<ushort>(5); _realm.Type = result.Read<byte>(5);
_realm.Type = result.Read<byte>(6); _realm.Flags = (RealmFlags)result.Read<byte>(6);
_realm.Flags = (RealmFlags)result.Read<byte>(7); _realm.Timezone = result.Read<byte>(7);
_realm.Timezone = result.Read<byte>(8); _realm.AllowedSecurityLevel = (AccountTypes)result.Read<byte>(8);
_realm.AllowedSecurityLevel = (AccountTypes)result.Read<byte>(9); _realm.PopulationLevel = result.Read<float>(9);
_realm.PopulationLevel = result.Read<float>(10); _realm.Build = result.Read<uint>(10);
_realm.Id.Region = result.Read<byte>(12); _realm.Id.Region = result.Read<byte>(11);
_realm.Id.Site = result.Read<byte>(13); _realm.Id.Site = result.Read<byte>(12);
_realm.Build = result.Read<uint>(11);
return true; return true;
} }