mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-31 06:07:37 +01:00
Core/Authserver: Added possibility to allow realm connections both from "world" and local networks.
This commit is contained in:
@@ -193,6 +193,8 @@ CREATE TABLE `realmlist` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(32) NOT NULL DEFAULT '',
|
||||
`address` varchar(255) NOT NULL DEFAULT '127.0.0.1',
|
||||
`localAddress` varchar(255) NOT NULL DEFAULT '127.0.0.1',
|
||||
`localSubnetMask` varchar(255) NOT NULL DEFAULT '255.255.255.0',
|
||||
`port` smallint(5) unsigned NOT NULL DEFAULT '8085',
|
||||
`icon` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`flag` tinyint(3) unsigned NOT NULL DEFAULT '2',
|
||||
|
||||
3
sql/updates/auth/2013_01_27_00_auth_realmlist.sql
Normal file
3
sql/updates/auth/2013_01_27_00_auth_realmlist.sql
Normal file
@@ -0,0 +1,3 @@
|
||||
ALTER TABLE `realmlist`
|
||||
ADD `localAddress` varchar(255) NOT NULL DEFAULT '127.0.0.1' AFTER `address`,
|
||||
ADD `localSubnetMask` varchar(255) NOT NULL DEFAULT '255.255.255.0' AFTER `localAddress`;
|
||||
@@ -31,12 +31,12 @@ void RealmList::Initialize(uint32 updateInterval)
|
||||
UpdateRealms(true);
|
||||
}
|
||||
|
||||
void RealmList::UpdateRealm(uint32 ID, const std::string& name, ACE_INET_Addr const& address, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float popu, uint32 build)
|
||||
void RealmList::UpdateRealm(uint32 id, const std::string& name, ACE_INET_Addr const& address, ACE_INET_Addr const& localAddr, ACE_INET_Addr const& localSubmask, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float popu, uint32 build)
|
||||
{
|
||||
// Create new if not exist or update existed
|
||||
Realm& realm = m_realms[name];
|
||||
|
||||
realm.m_ID = ID;
|
||||
realm.m_ID = id;
|
||||
realm.name = name;
|
||||
realm.icon = icon;
|
||||
realm.flag = flag;
|
||||
@@ -45,7 +45,9 @@ void RealmList::UpdateRealm(uint32 ID, const std::string& name, ACE_INET_Addr co
|
||||
realm.populationLevel = popu;
|
||||
|
||||
// Append port to IP address.
|
||||
address.addr_to_string(realm.address, ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 16);
|
||||
realm.ExternalAddress = address;
|
||||
realm.LocalAddress = localAddr;
|
||||
realm.LocalSubnetMask = localSubmask;
|
||||
realm.gamebuild = build;
|
||||
}
|
||||
|
||||
@@ -77,23 +79,27 @@ void RealmList::UpdateRealms(bool init)
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
uint32 realmId = fields[0].GetUInt32();
|
||||
std::string name = fields[1].GetString();
|
||||
std::string address = fields[2].GetString();
|
||||
uint16 port = fields[3].GetUInt16();
|
||||
uint8 icon = fields[4].GetUInt8();
|
||||
RealmFlags flag = RealmFlags(fields[5].GetUInt8());
|
||||
uint8 timezone = fields[6].GetUInt8();
|
||||
uint8 allowedSecurityLevel = fields[7].GetUInt8();
|
||||
float pop = fields[8].GetFloat();
|
||||
uint32 build = fields[9].GetUInt32();
|
||||
uint32 realmId = fields[0].GetUInt32();
|
||||
std::string name = fields[1].GetString();
|
||||
std::string externalAddress = fields[2].GetString();
|
||||
std::string localAddress = fields[3].GetString();
|
||||
std::string localSubmask = fields[4].GetString();
|
||||
uint16 port = fields[5].GetUInt16();
|
||||
uint8 icon = fields[6].GetUInt8();
|
||||
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();
|
||||
|
||||
ACE_INET_Addr addr(port, address.c_str(), AF_INET);
|
||||
ACE_INET_Addr externalAddr(port, externalAddress.c_str(), AF_INET);
|
||||
ACE_INET_Addr localAddr(port, localAddress.c_str(), AF_INET);
|
||||
ACE_INET_Addr submask(0, localSubmask.c_str(), AF_INET);
|
||||
|
||||
UpdateRealm(realmId, name, addr, icon, flag, timezone, (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop, build);
|
||||
UpdateRealm(realmId, name, externalAddr, localAddr, submask, icon, flag, timezone, (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop, build);
|
||||
|
||||
if (init)
|
||||
sLog->outInfo(LOG_FILTER_AUTHSERVER, "Added realm \"%s\" at %s.", name.c_str(), m_realms[name].address);
|
||||
sLog->outInfo(LOG_FILTER_AUTHSERVER, "Added realm \"%s\" at %s:%u.", name.c_str(), m_realms[name].ExternalAddress.get_host_addr(), port);
|
||||
}
|
||||
while (result->NextRow());
|
||||
}
|
||||
|
||||
@@ -40,7 +40,9 @@ enum RealmFlags
|
||||
// Storage object for a realm
|
||||
struct Realm
|
||||
{
|
||||
char address[ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 16];
|
||||
ACE_INET_Addr ExternalAddress;
|
||||
ACE_INET_Addr LocalAddress;
|
||||
ACE_INET_Addr LocalSubnetMask;
|
||||
std::string name;
|
||||
uint8 icon;
|
||||
RealmFlags flag;
|
||||
@@ -72,7 +74,7 @@ public:
|
||||
|
||||
private:
|
||||
void UpdateRealms(bool init=false);
|
||||
void UpdateRealm(uint32 ID, const std::string& name, ACE_INET_Addr const& address, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float popu, uint32 build);
|
||||
void UpdateRealm(uint32 id, const std::string& name, ACE_INET_Addr const& address, ACE_INET_Addr const& localAddr, ACE_INET_Addr const& localSubmask, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float popu, uint32 build);
|
||||
|
||||
RealmMap m_realms;
|
||||
uint32 m_UpdateInterval;
|
||||
|
||||
@@ -818,6 +818,28 @@ bool AuthSocket::_HandleReconnectProof()
|
||||
}
|
||||
}
|
||||
|
||||
ACE_INET_Addr const& AuthSocket::GetAddressForClient(Realm const& realm, ACE_INET_Addr const& clientAddr)
|
||||
{
|
||||
// Attempt to send best address for client
|
||||
if (clientAddr.is_loopback())
|
||||
{
|
||||
// Try guessing if realm is also connected locally
|
||||
if (realm.LocalAddress.is_loopback() || realm.ExternalAddress.is_loopback())
|
||||
return clientAddr;
|
||||
|
||||
// Assume that user connecting from the machine that authserver is located on
|
||||
// has all realms available in his local network
|
||||
return realm.LocalAddress;
|
||||
}
|
||||
|
||||
// Check if connecting client is in the same network
|
||||
if (IsIPAddrInNetwork(realm.LocalAddress, clientAddr, realm.LocalSubnetMask))
|
||||
return realm.LocalAddress;
|
||||
|
||||
// Return external IP
|
||||
return realm.ExternalAddress;
|
||||
}
|
||||
|
||||
// Realm List command handler
|
||||
bool AuthSocket::_HandleRealmList()
|
||||
{
|
||||
@@ -845,6 +867,9 @@ bool AuthSocket::_HandleRealmList()
|
||||
// Update realm list if need
|
||||
sRealmList->UpdateIfNeed();
|
||||
|
||||
ACE_INET_Addr clientAddr;
|
||||
socket().peer().get_remote_addr(clientAddr);
|
||||
|
||||
// Circle through realms in the RealmList and construct the return packet (including # of user characters in each realm)
|
||||
ByteBuffer pkt;
|
||||
|
||||
@@ -876,6 +901,9 @@ bool AuthSocket::_HandleRealmList()
|
||||
name = ss.str();
|
||||
}
|
||||
|
||||
// We don't need the port number from which client connects with but the realm's port
|
||||
clientAddr.set_port_number(i->second.ExternalAddress.get_port_number());
|
||||
|
||||
uint8 lock = (i->second.allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0;
|
||||
|
||||
uint8 AmountOfCharacters = 0;
|
||||
@@ -891,7 +919,7 @@ bool AuthSocket::_HandleRealmList()
|
||||
pkt << lock; // if 1, then realm locked
|
||||
pkt << uint8(flag); // RealmFlags
|
||||
pkt << name;
|
||||
pkt << i->second.address;
|
||||
pkt << GetAddressString(GetAddressForClient(i->second, clientAddr));
|
||||
pkt << i->second.populationLevel;
|
||||
pkt << AmountOfCharacters;
|
||||
pkt << i->second.timezone; // realm category
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
#include "BigNumber.h"
|
||||
#include "RealmSocket.h"
|
||||
|
||||
class ACE_INET_Addr;
|
||||
struct Realm;
|
||||
|
||||
// Handle login commands
|
||||
class AuthSocket: public RealmSocket::Session
|
||||
{
|
||||
@@ -36,6 +39,8 @@ public:
|
||||
virtual void OnAccept(void);
|
||||
virtual void OnClose(void);
|
||||
|
||||
static ACE_INET_Addr const& GetAddressForClient(Realm const& realm, ACE_INET_Addr const& clientAddr);
|
||||
|
||||
bool _HandleLogonChallenge();
|
||||
bool _HandleLogonProof();
|
||||
bool _HandleReconnectChallenge();
|
||||
|
||||
@@ -22,7 +22,7 @@ void LoginDatabaseConnection::DoPrepareStatements()
|
||||
if (!m_reconnecting)
|
||||
m_stmts.resize(MAX_LOGINDATABASE_STATEMENTS);
|
||||
|
||||
PrepareStatement(LOGIN_SEL_REALMLIST, "SELECT id, name, address, port, icon, flag, timezone, allowedSecurityLevel, population, gamebuild FROM realmlist WHERE flag <> 3 ORDER BY name", CONNECTION_SYNCH);
|
||||
PrepareStatement(LOGIN_SEL_REALMLIST, "SELECT id, name, address, localAddress, localSubnetMask, port, icon, flag, timezone, allowedSecurityLevel, population, gamebuild 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_BANNED, "SELECT * FROM ip_banned WHERE ip = ?", CONNECTION_SYNCH);
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include "SFMT.h"
|
||||
#include "Errors.h" // for ASSERT
|
||||
#include <ace/TSS_T.h>
|
||||
#include <ace/INET_Addr.h>
|
||||
|
||||
typedef ACE_TSS<SFMTRand> SFMTRandTSS;
|
||||
static SFMTRandTSS sfmtRand;
|
||||
@@ -239,6 +238,21 @@ bool IsIPAddress(char const* ipaddress)
|
||||
return inet_addr(ipaddress) != INADDR_NONE;
|
||||
}
|
||||
|
||||
std::string GetAddressString(ACE_INET_Addr const& addr)
|
||||
{
|
||||
char buf[ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 16];
|
||||
addr.addr_to_string(buf, ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 16);
|
||||
return buf;
|
||||
}
|
||||
|
||||
bool IsIPAddrInNetwork(ACE_INET_Addr const& net, ACE_INET_Addr const& addr, ACE_INET_Addr const& subnetMask)
|
||||
{
|
||||
uint32 mask = subnetMask.get_ip_address();
|
||||
if ((net.get_ip_address() & mask) == (addr.get_ip_address() & mask))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// create PID file
|
||||
uint32 CreatePIDFile(const std::string& filename)
|
||||
{
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <ace/INET_Addr.h>
|
||||
|
||||
// Searcher for map of structs
|
||||
template<typename T, class S> struct Finder
|
||||
@@ -343,6 +344,13 @@ void utf8printf(FILE* out, const char *str, ...);
|
||||
void vutf8printf(FILE* out, const char *str, va_list* ap);
|
||||
|
||||
bool IsIPAddress(char const* ipaddress);
|
||||
|
||||
/// Checks if address belongs to the a network with specified submask
|
||||
bool IsIPAddrInNetwork(ACE_INET_Addr const& net, ACE_INET_Addr const& addr, ACE_INET_Addr const& subnetMask);
|
||||
|
||||
/// Transforms ACE_INET_Addr address into string format "dotted_ip:port"
|
||||
std::string GetAddressString(ACE_INET_Addr const& addr);
|
||||
|
||||
uint32 CreatePIDFile(const std::string& filename);
|
||||
|
||||
std::string ByteArrayToHexStr(uint8 const* bytes, uint32 length, bool reverse = false);
|
||||
|
||||
Reference in New Issue
Block a user