From 36712db0f11cf2d68c292cc99e7691b643128e8c Mon Sep 17 00:00:00 2001 From: heinrich5991 Date: Mon, 6 May 2024 16:15:51 +0200 Subject: [PATCH] Use network tokens in big-endian byte order consistently Previously, it was handled inconsistently on big-endian machines and caused connection failures. --- src/engine/server/register.cpp | 6 ++---- src/engine/shared/network.cpp | 20 +++++++++++++++----- src/engine/shared/network.h | 3 ++- src/engine/shared/network_conn.cpp | 5 ----- src/engine/shared/network_server.cpp | 5 ----- 5 files changed, 19 insertions(+), 20 deletions(-) diff --git a/src/engine/server/register.cpp b/src/engine/server/register.cpp index c1ab63e83..3092ea2dc 100644 --- a/src/engine/server/register.cpp +++ b/src/engine/server/register.cpp @@ -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); diff --git a/src/engine/shared/network.cpp b/src/engine/shared/network.cpp index 89d235f90..40e2b5dff 100644 --- a/src/engine/shared/network.cpp +++ b/src/engine/shared/network.cpp @@ -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) diff --git a/src/engine/shared/network.h b/src/engine/shared/network.h index 4e80dbb41..99215a3b7 100644 --- a/src/engine/shared/network.h +++ b/src/engine/shared/network.h @@ -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]; diff --git a/src/engine/shared/network_conn.cpp b/src/engine/shared/network_conn.cpp index 50961465d..2689f8808 100644 --- a/src/engine/shared/network_conn.cpp +++ b/src/engine/shared/network_conn.cpp @@ -4,11 +4,6 @@ #include "network.h" #include -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)); diff --git a/src/engine/shared/network_server.cpp b/src/engine/shared/network_server.cpp index 9262863a0..c963b8514 100644 --- a/src/engine/shared/network_server.cpp +++ b/src/engine/shared/network_server.cpp @@ -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