"RealmListPort" 3724
"ServerPort" 8093
"Host" "0.0.0.0"
"ISHost" "0.0.0.0"
RemotePassword 经过hash后传递。
HOST:RealmListPort接收的是来自客户端的连接,以ListenSocket<AuthSocket>的形式存在。
ISHOST:ServerPort作为服务器监听并处理来自World或者Realm的通讯,以ListenSocket<LogonCommServerSocket>的形式存在。
template<class T>
class SERVER_DECL ListenSocket : public ThreadContext
ListenSocket继承自 ThreadContext 传递给线程池由线程池执行,CThreadPool::ExecuteTask(ThreadContext * ExecutionTarget)
认证过程见AuthSocket
分区信息的处理见AccountCache中的 InformationCore,放在这里可能不太合适!
解释Realm(WS)与Logon的连接验证方式:
1)Logon作为服务器,监听,默认端口8093,在Main()中
ListenSocket<LogonCommServerSocket> * sl = new ListenSocket<LogonCommServerSocket>(shost.c_str(), sport);
2)当Logon接收到连接,首先是需要验证,由void HandleAuthChallenge(WorldPacket & recvData);处理验证,验证需要密码,密码分别在Realm与Logon的配置文件有设定RemotePassword。Logon启动时将密码经过加密后,与Realm发来的加密过的密码相比较判断是否合法,此外Logon严格显示连接的IP,由 AllowedIPs和AllowedModIPs设定。
3)最后由Logon返回验证信息。如果通过则建立起连接通讯。
从宏观上解释客户端的验证和连接,
1)首先客户端登录,连接到Logon的3724端口。并由Logon信息返回是否登陆成功。
其中由void AuthSocket::HandleChallenge()判断账号是否禁用、账户冻结、客户端补丁是否最新等。
由void AuthSocket::HandleProof()处理账户的是否登录成功,验证过程是找不到明文的密码,如果不加密(见注)那么
hash.UpdateData((Username + ":" + Password));
hash.Finalize();
memcpy(acct->SrpHash, hash.GetDigest(), 20);
也就是说Username与Password组合hash后保存在 Account结构的SrpHash成员 uint8 SrpHash[20];
2)如果HandleProof()验证通过则会为该账户分配SessionKey
const char* m_sessionkey_hex = m_sessionkey.AsHexStr();
并将账户标记为已验证:
m_authenticated = true;
3)接下来客户端会请求得到Realm——分区表,#define REALM_LIST 16
4)当Logon收到该消息后交给 AuthSocket::HandleRealmlist 处理,该函数调用InformationCore的SendRealm()方法:
sInfoCore.SendRealms(this); //#define sInfoCore InformationCore::getSingleton()
5)Logon会将注册的分区表发送给客户端,其中包含Realm的服务器名,地址,端口信息等
但是地址和端口是一个整体,就像在Realm配置文件中看到的那样:
data << itr->second->Address;
string Address;
realm->Address = Config.RealmConfig.GetStringVA("Address", "127.0.0.1:8129", "Realm%u", i);
6)由此客户端将连接至Realm服务器!
7)Realm收到请求后向Logon Server发送消息
Logon Server将消息由
void LogonCommServerSocket::HandleSessionRequest(WorldPacket & recvData)
函数处理,通过
request_id;
account_name;
验证账户的合法性,如果通过则返回SessionKey。
登录连接的过程至此就结束了。
注:配置文件中的UseEncryptedPasswords不是指RemotePassword是否加密而是指Account表中的账户密码是否加密,搜索m_encryptedPasswords可证。