mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-23 18:36:31 +01:00
Core/Network: Refactor local/remote ip address selection code and allow using hostnames in LoginREST bnetserver config options
This commit is contained in:
@@ -32,6 +32,7 @@
|
||||
#include "DeadlineTimer.h"
|
||||
#include "GitRevision.h"
|
||||
#include "IPLocation.h"
|
||||
#include "IpNetwork.h"
|
||||
#include "LoginRESTService.h"
|
||||
#include "MySQLThreading.h"
|
||||
#include "OpenSSLCrypto.h"
|
||||
@@ -192,6 +193,8 @@ int main(int argc, char** argv)
|
||||
|
||||
std::shared_ptr<Trinity::Asio::IoContext> ioContext = std::make_shared<Trinity::Asio::IoContext>();
|
||||
|
||||
Trinity::Net::ScanLocalNetworks();
|
||||
|
||||
// Start the listening port (acceptor) for auth connections
|
||||
int32 bnport = sConfigMgr->GetIntDefault("BattlenetPort", 1119);
|
||||
if (bnport < 0 || bnport > 0xFFFF)
|
||||
|
||||
@@ -90,7 +90,8 @@ bool LoginRESTService::Start(Trinity::Asio::IoContext* ioContext)
|
||||
return false;
|
||||
}
|
||||
|
||||
_externalAddress = *externalAddress;
|
||||
_externalEndpoint = *externalAddress;
|
||||
_externalHostname = Trinity::StringFormat("{}:{}", configuredAddress, _port);
|
||||
|
||||
configuredAddress = sConfigMgr->GetStringDefault("LoginREST.LocalAddress", "127.0.0.1");
|
||||
Optional<boost::asio::ip::tcp::endpoint> localAddress = resolver.Resolve(boost::asio::ip::tcp::v4(), configuredAddress, std::to_string(_port));
|
||||
@@ -100,8 +101,8 @@ bool LoginRESTService::Start(Trinity::Asio::IoContext* ioContext)
|
||||
return false;
|
||||
}
|
||||
|
||||
_localAddress = *localAddress;
|
||||
_localNetmask = Trinity::Net::GetDefaultNetmaskV4(_localAddress.address().to_v4());
|
||||
_localEndpoint = *localAddress;
|
||||
_localHostname = Trinity::StringFormat("{}:{}", configuredAddress, _port);
|
||||
|
||||
// set up form inputs
|
||||
Battlenet::JSON::Login::FormInput* input;
|
||||
@@ -135,17 +136,48 @@ void LoginRESTService::Stop()
|
||||
_thread.join();
|
||||
}
|
||||
|
||||
boost::asio::ip::tcp::endpoint const& LoginRESTService::GetAddressForClient(boost::asio::ip::address const& address) const
|
||||
boost::asio::ip::tcp::endpoint const& LoginRESTService::GetEndpointForClient(boost::asio::ip::address const& address) const
|
||||
{
|
||||
std::array<boost::asio::ip::address, 2> addresses = std::array{ _externalEndpoint.address(), _localEndpoint.address() };
|
||||
if (auto addressIndex = Trinity::Net::SelectAddressForClient(address, addresses))
|
||||
{
|
||||
switch (*addressIndex)
|
||||
{
|
||||
case 0:
|
||||
return _externalEndpoint;
|
||||
case 1:
|
||||
return _localEndpoint;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (address.is_loopback())
|
||||
return _localAddress;
|
||||
else if (_localAddress.address().is_loopback())
|
||||
return _externalAddress;
|
||||
return _localEndpoint;
|
||||
|
||||
if (Trinity::Net::IsInNetwork(_localAddress.address().to_v4(), _localNetmask, address.to_v4()))
|
||||
return _localAddress;
|
||||
return _externalEndpoint;
|
||||
}
|
||||
|
||||
return _externalAddress;
|
||||
std::string const& LoginRESTService::GetHostnameForClient(boost::asio::ip::address const& address) const
|
||||
{
|
||||
std::array<boost::asio::ip::address, 2> addresses = std::array{ _externalEndpoint.address(), _localEndpoint.address() };
|
||||
if (auto addressIndex = Trinity::Net::SelectAddressForClient(address, addresses))
|
||||
{
|
||||
switch (*addressIndex)
|
||||
{
|
||||
case 0:
|
||||
return _externalHostname;
|
||||
case 1:
|
||||
return _localHostname;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (address.is_loopback())
|
||||
return _localHostname;
|
||||
|
||||
return _externalHostname;
|
||||
}
|
||||
|
||||
void LoginRESTService::Run()
|
||||
@@ -298,7 +330,7 @@ int32 LoginRESTService::HandleGetGameAccounts(std::shared_ptr<AsyncRequest> requ
|
||||
|
||||
int32 LoginRESTService::HandleGetPortal(std::shared_ptr<AsyncRequest> request)
|
||||
{
|
||||
boost::asio::ip::tcp::endpoint const& endpoint = GetAddressForClient(boost::asio::ip::address_v4(request->GetClient()->ip));
|
||||
boost::asio::ip::tcp::endpoint const& endpoint = GetEndpointForClient(boost::asio::ip::address_v4(request->GetClient()->ip));
|
||||
std::string response = Trinity::StringFormat("{}:{}", endpoint.address().to_string(), sConfigMgr->GetIntDefault("BattlenetPort", 1119));
|
||||
|
||||
soap_response(request->GetClient(), SOAP_FILE);
|
||||
|
||||
@@ -46,7 +46,8 @@ public:
|
||||
bool Start(Trinity::Asio::IoContext* ioContext);
|
||||
void Stop();
|
||||
|
||||
boost::asio::ip::tcp::endpoint const& GetAddressForClient(boost::asio::ip::address const& address) const;
|
||||
boost::asio::ip::tcp::endpoint const& GetEndpointForClient(boost::asio::ip::address const& address) const;
|
||||
std::string const& GetHostnameForClient(boost::asio::ip::address const& address) const;
|
||||
|
||||
private:
|
||||
void Run();
|
||||
@@ -101,9 +102,10 @@ private:
|
||||
Battlenet::JSON::Login::FormInputs _formInputs;
|
||||
std::string _bindIP;
|
||||
int32 _port;
|
||||
boost::asio::ip::tcp::endpoint _externalAddress;
|
||||
boost::asio::ip::tcp::endpoint _localAddress;
|
||||
boost::asio::ip::address_v4 _localNetmask;
|
||||
std::string _externalHostname;
|
||||
boost::asio::ip::tcp::endpoint _externalEndpoint;
|
||||
std::string _localHostname;
|
||||
boost::asio::ip::tcp::endpoint _localEndpoint;
|
||||
uint32 _loginTicketDuration;
|
||||
|
||||
HttpMethodHandlerMap _getHandlers;
|
||||
|
||||
@@ -232,11 +232,11 @@ uint32 Battlenet::Session::HandleLogon(authentication::v1::LogonRequest const* l
|
||||
if (logonRequest->has_cached_web_credentials())
|
||||
return VerifyWebCredentials(logonRequest->cached_web_credentials(), continuation);
|
||||
|
||||
boost::asio::ip::tcp::endpoint const& endpoint = sLoginService.GetAddressForClient(GetRemoteIpAddress());
|
||||
std::string const& hostname = sLoginService.GetHostnameForClient(GetRemoteIpAddress());
|
||||
|
||||
challenge::v1::ChallengeExternalRequest externalChallenge;
|
||||
externalChallenge.set_payload_type("web_auth_url");
|
||||
externalChallenge.set_payload(Trinity::StringFormat("https://{}:{}/bnetserver/login/", endpoint.address().to_string(), endpoint.port()));
|
||||
externalChallenge.set_payload(Trinity::StringFormat("https://{}/bnetserver/login/", hostname));
|
||||
Service<challenge::v1::ChallengeListener>(this).OnExternalChallenge(&externalChallenge);
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ void LoginDatabaseConnection::DoPrepareStatements()
|
||||
if (!m_reconnecting)
|
||||
m_stmts.resize(MAX_LOGINDATABASE_STATEMENTS);
|
||||
|
||||
PrepareStatement(LOGIN_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", CONNECTION_SYNCH);
|
||||
PrepareStatement(LOGIN_SEL_REALMLIST, "SELECT id, name, address, localAddress, port, icon, flag, timezone, allowedSecurityLevel, population, gamebuild, Region, Battlegroup FROM realmlist WHERE flag <> 3 ORDER BY name", CONNECTION_SYNCH);
|
||||
PrepareStatement(LOGIN_DEL_EXPIRED_IP_BANS, "DELETE FROM ip_banned WHERE unbandate<>bandate AND unbandate<=UNIX_TIMESTAMP()", CONNECTION_ASYNC);
|
||||
PrepareStatement(LOGIN_UPD_EXPIRED_ACCOUNT_BANS, "UPDATE account_banned SET active = 0 WHERE active = 1 AND unbandate<>bandate AND unbandate<=UNIX_TIMESTAMP()", CONNECTION_ASYNC);
|
||||
PrepareStatement(LOGIN_SEL_IP_INFO, "SELECT unbandate > UNIX_TIMESTAMP() OR unbandate = bandate AS banned, NULL as country FROM ip_banned WHERE ip = ?", CONNECTION_ASYNC);
|
||||
|
||||
@@ -31,31 +31,24 @@ void Realm::SetName(std::string name)
|
||||
|
||||
boost::asio::ip::address Realm::GetAddressForClient(boost::asio::ip::address const& clientAddr) const
|
||||
{
|
||||
boost::asio::ip::address realmIp;
|
||||
|
||||
// Attempt to send best address for client
|
||||
if (clientAddr.is_loopback())
|
||||
std::array<boost::asio::ip::address, 2> addresses = std::array{ *ExternalAddress, * LocalAddress };
|
||||
if (auto addressIndex = Trinity::Net::SelectAddressForClient(clientAddr, addresses))
|
||||
{
|
||||
// Try guessing if realm is also connected locally
|
||||
if (LocalAddress->is_loopback() || ExternalAddress->is_loopback())
|
||||
realmIp = clientAddr;
|
||||
else
|
||||
switch (*addressIndex)
|
||||
{
|
||||
// Assume that user connecting from the machine that bnetserver is located on
|
||||
// has all realms available in his local network
|
||||
realmIp = *LocalAddress;
|
||||
case 0:
|
||||
return *ExternalAddress;
|
||||
case 1:
|
||||
return *LocalAddress;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (clientAddr.is_v4() && Trinity::Net::IsInNetwork(LocalAddress->to_v4(), LocalSubnetMask->to_v4(), clientAddr.to_v4()))
|
||||
realmIp = *LocalAddress;
|
||||
else
|
||||
realmIp = *ExternalAddress;
|
||||
}
|
||||
|
||||
// Return external IP
|
||||
return realmIp;
|
||||
if (clientAddr.is_loopback())
|
||||
return *LocalAddress;
|
||||
|
||||
return *ExternalAddress;
|
||||
}
|
||||
|
||||
uint32 Realm::GetConfigId() const
|
||||
|
||||
@@ -94,7 +94,7 @@ void RealmList::LoadBuildInfo()
|
||||
}
|
||||
|
||||
void RealmList::UpdateRealm(Realm& realm, Battlenet::RealmHandle const& id, uint32 build, std::string const& name,
|
||||
boost::asio::ip::address&& address, boost::asio::ip::address&& localAddr, boost::asio::ip::address&& localSubmask,
|
||||
boost::asio::ip::address&& address, boost::asio::ip::address&& localAddr,
|
||||
uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel,
|
||||
float population)
|
||||
{
|
||||
@@ -111,8 +111,6 @@ void RealmList::UpdateRealm(Realm& realm, Battlenet::RealmHandle const& id, uint
|
||||
realm.ExternalAddress = std::make_unique<boost::asio::ip::address>(std::move(address));
|
||||
if (!realm.LocalAddress || *realm.LocalAddress != localAddr)
|
||||
realm.LocalAddress = std::make_unique<boost::asio::ip::address>(std::move(localAddr));
|
||||
if (!realm.LocalSubnetMask || *realm.LocalSubnetMask != localSubmask)
|
||||
realm.LocalSubnetMask = std::make_unique<boost::asio::ip::address>(std::move(localSubmask));
|
||||
realm.Port = port;
|
||||
}
|
||||
|
||||
@@ -145,7 +143,6 @@ void RealmList::UpdateRealms(boost::system::error_code const& error)
|
||||
std::string name = fields[1].GetString();
|
||||
std::string externalAddressString = fields[2].GetString();
|
||||
std::string localAddressString = fields[3].GetString();
|
||||
std::string localSubmaskString = fields[4].GetString();
|
||||
|
||||
Optional<boost::asio::ip::tcp::endpoint> externalAddress = _resolver->Resolve(boost::asio::ip::tcp::v4(), externalAddressString, "");
|
||||
if (!externalAddress)
|
||||
@@ -161,30 +158,23 @@ void RealmList::UpdateRealms(boost::system::error_code const& error)
|
||||
continue;
|
||||
}
|
||||
|
||||
Optional<boost::asio::ip::tcp::endpoint> localSubmask = _resolver->Resolve(boost::asio::ip::tcp::v4(), localSubmaskString, "");
|
||||
if (!localSubmask)
|
||||
{
|
||||
TC_LOG_ERROR("realmlist", "Could not resolve localSubnetMask {} for realm \"{}\" id {}", localSubmaskString, name, realmId);
|
||||
continue;
|
||||
}
|
||||
|
||||
uint16 port = fields[5].GetUInt16();
|
||||
uint8 icon = fields[6].GetUInt8();
|
||||
uint16 port = fields[4].GetUInt16();
|
||||
uint8 icon = fields[5].GetUInt8();
|
||||
if (icon == REALM_TYPE_FFA_PVP)
|
||||
icon = REALM_TYPE_PVP;
|
||||
if (icon >= MAX_CLIENT_REALM_TYPE)
|
||||
icon = REALM_TYPE_NORMAL;
|
||||
RealmFlags flag = RealmFlags(fields[7].GetUInt8());
|
||||
uint8 timezone = fields[8].GetUInt8();
|
||||
uint8 allowedSecurityLevel = fields[9].GetUInt8();
|
||||
float pop = fields[10].GetFloat();
|
||||
uint32 build = fields[11].GetUInt32();
|
||||
uint8 region = fields[12].GetUInt8();
|
||||
uint8 battlegroup = fields[13].GetUInt8();
|
||||
RealmFlags flag = RealmFlags(fields[6].GetUInt8());
|
||||
uint8 timezone = fields[7].GetUInt8();
|
||||
uint8 allowedSecurityLevel = fields[8].GetUInt8();
|
||||
float pop = fields[9].GetFloat();
|
||||
uint32 build = fields[10].GetUInt32();
|
||||
uint8 region = fields[11].GetUInt8();
|
||||
uint8 battlegroup = fields[12].GetUInt8();
|
||||
|
||||
Battlenet::RealmHandle id{ region, battlegroup, realmId };
|
||||
|
||||
UpdateRealm(newRealms[id], id, build, name, externalAddress->address(), localAddress->address(), localSubmask->address(), port, icon,
|
||||
UpdateRealm(newRealms[id], id, build, name, externalAddress->address(), localAddress->address(), port, icon,
|
||||
flag, timezone, (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop);
|
||||
|
||||
newSubRegions.insert(Battlenet::RealmHandle{ region, battlegroup, 0 }.GetAddressString());
|
||||
|
||||
@@ -98,7 +98,7 @@ private:
|
||||
void LoadBuildInfo();
|
||||
void UpdateRealms(boost::system::error_code const& error);
|
||||
void UpdateRealm(Realm& realm, Battlenet::RealmHandle const& id, uint32 build, std::string const& name,
|
||||
boost::asio::ip::address&& address, boost::asio::ip::address&& localAddr, boost::asio::ip::address&& localSubmask,
|
||||
boost::asio::ip::address&& address, boost::asio::ip::address&& localAddr,
|
||||
uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population);
|
||||
|
||||
std::vector<RealmBuildInfo> _builds;
|
||||
|
||||
@@ -34,10 +34,10 @@
|
||||
#include "GitRevision.h"
|
||||
#include "InstanceLockMgr.h"
|
||||
#include "IoContext.h"
|
||||
#include "IpNetwork.h"
|
||||
#include "MapManager.h"
|
||||
#include "Metric.h"
|
||||
#include "MySQLThreading.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "OpenSSLCrypto.h"
|
||||
#include "OutdoorPvP/OutdoorPvPMgr.h"
|
||||
#include "ProcessPriority.h"
|
||||
@@ -290,6 +290,8 @@ extern int main(int argc, char** argv)
|
||||
if (vm.count("update-databases-only"))
|
||||
return 0;
|
||||
|
||||
Trinity::Net::ScanLocalNetworks();
|
||||
|
||||
// Set server offline (not connectable)
|
||||
LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag | {} WHERE id = '{}'", REALM_FLAG_OFFLINE, realm.Id.Realm);
|
||||
|
||||
@@ -619,7 +621,6 @@ bool LoadRealmInfo()
|
||||
realm.Build = realmListRealm->Build;
|
||||
realm.ExternalAddress = std::make_unique<boost::asio::ip::address>(*realmListRealm->ExternalAddress);
|
||||
realm.LocalAddress = std::make_unique<boost::asio::ip::address>(*realmListRealm->LocalAddress);
|
||||
realm.LocalSubnetMask = std::make_unique<boost::asio::ip::address>(*realmListRealm->LocalSubnetMask);
|
||||
realm.Port = realmListRealm->Port;
|
||||
realm.Name = realmListRealm->Name;
|
||||
realm.NormalizedName = realmListRealm->NormalizedName;
|
||||
|
||||
Reference in New Issue
Block a user