Use network tokens in big-endian byte order consistently

Previously, it was handled inconsistently on big-endian machines and
caused connection failures.
This commit is contained in:
heinrich5991 2024-05-06 16:15:51 +02:00
parent d4e3f6fc01
commit 36712db0f1
5 changed files with 19 additions and 20 deletions

View file

@ -518,10 +518,8 @@ CRegister::CRegister(CConfig *pConfig, IConsole *pConsole, IEngine *pEngine, IHt
FormatUuid(m_ChallengeSecret, m_aVerifyPacketPrefix + HEADER_LEN, sizeof(m_aVerifyPacketPrefix) - HEADER_LEN);
m_aVerifyPacketPrefix[HEADER_LEN + UUID_MAXSTRSIZE - 1] = ':';
// The DDNet code uses the `unsigned` security token in memory byte order.
unsigned char aTokenBytes[sizeof(int32_t)];
mem_copy(aTokenBytes, &SixupSecurityToken, sizeof(aTokenBytes));
str_format(m_aConnlessTokenHex, sizeof(m_aConnlessTokenHex), "%08x", bytes_be_to_uint(aTokenBytes));
// The DDNet code uses the `unsigned` security token in big-endian byte order.
str_format(m_aConnlessTokenHex, sizeof(m_aConnlessTokenHex), "%08x", SixupSecurityToken);
m_pConsole->Chain("sv_register", ConchainOnConfigChange, this);
m_pConsole->Chain("sv_register_extra", ConchainOnConfigChange, this);

View file

@ -8,6 +8,16 @@
const unsigned char SECURITY_TOKEN_MAGIC[4] = {'T', 'K', 'E', 'N'};
SECURITY_TOKEN ToSecurityToken(const unsigned char *pData)
{
return bytes_be_to_uint(pData);
}
void WriteSecurityToken(unsigned char *pData, SECURITY_TOKEN Token)
{
uint_to_bytes_be(pData, Token);
}
void CNetRecvUnpacker::Clear()
{
m_Valid = false;
@ -131,13 +141,13 @@ void CNetBase::SendPacket(NETSOCKET Socket, NETADDR *pAddr, CNetPacketConstruct
if(Sixup)
{
HeaderSize += sizeof(SecurityToken);
mem_copy(&aBuffer[3], &SecurityToken, sizeof(SecurityToken));
WriteSecurityToken(aBuffer + 3, SecurityToken);
}
else if(SecurityToken != NET_SECURITY_TOKEN_UNSUPPORTED)
{
// append security token
// if SecurityToken is NET_SECURITY_TOKEN_UNKNOWN we will still append it hoping to negotiate it
mem_copy(&pPacket->m_aChunkData[pPacket->m_DataSize], &SecurityToken, sizeof(SecurityToken));
WriteSecurityToken(pPacket->m_aChunkData + pPacket->m_DataSize, SecurityToken);
pPacket->m_DataSize += sizeof(SecurityToken);
}
@ -223,8 +233,8 @@ int CNetBase::UnpackPacket(unsigned char *pBuffer, int Size, CNetPacketConstruct
if(Sixup)
{
mem_copy(pSecurityToken, &pBuffer[1], sizeof(*pSecurityToken));
mem_copy(pResponseToken, &pBuffer[5], sizeof(*pResponseToken));
*pSecurityToken = ToSecurityToken(pBuffer + 1);
*pResponseToken = ToSecurityToken(pBuffer + 5);
}
pPacket->m_Flags = NET_PACKETFLAG_CONNLESS;
@ -264,7 +274,7 @@ int CNetBase::UnpackPacket(unsigned char *pBuffer, int Size, CNetPacketConstruct
Flags |= NET_PACKETFLAG_COMPRESSION;
pPacket->m_Flags = Flags;
mem_copy(pSecurityToken, &pBuffer[3], sizeof(*pSecurityToken));
*pSecurityToken = ToSecurityToken(pBuffer + 3);
}
if(pPacket->m_Flags & NET_PACKETFLAG_COMPRESSION)

View file

@ -97,7 +97,8 @@ enum
typedef int SECURITY_TOKEN;
SECURITY_TOKEN ToSecurityToken(unsigned char *pData);
SECURITY_TOKEN ToSecurityToken(const unsigned char *pData);
void WriteSecurityToken(unsigned char *pData, SECURITY_TOKEN Token);
extern const unsigned char SECURITY_TOKEN_MAGIC[4];

View file

@ -4,11 +4,6 @@
#include "network.h"
#include <base/system.h>
SECURITY_TOKEN ToSecurityToken(unsigned char *pData)
{
return (int)pData[0] | (pData[1] << 8) | (pData[2] << 16) | (pData[3] << 24);
}
void CNetConnection::ResetStats()
{
mem_zero(&m_Stats, sizeof(m_Stats));

View file

@ -36,11 +36,6 @@ const unsigned char g_aDummyMapData[] = {
0x78, 0x9C, 0x63, 0x64, 0x60, 0x60, 0x60, 0x44, 0xC2, 0x00, 0x00, 0x38,
0x00, 0x05};
static SECURITY_TOKEN ToSecurityToken(const unsigned char *pData)
{
return (int)pData[0] | (pData[1] << 8) | (pData[2] << 16) | (pData[3] << 24);
}
bool CNetServer::Open(NETADDR BindAddr, CNetBan *pNetBan, int MaxClients, int MaxClientsPerIp)
{
// zero out the whole structure