From e91d26b8ac7ab50913c709ed3beec90a115cfe61 Mon Sep 17 00:00:00 2001 From: oy Date: Thu, 19 Mar 2015 09:57:47 +0100 Subject: [PATCH] force vital check on essential cl/srv messages and added additional sequence checking --- src/engine/client/client.cpp | 27 ++++++++++++++------------ src/engine/server/server.cpp | 16 +++++++-------- src/engine/shared/network.cpp | 2 +- src/engine/shared/network.h | 1 + src/engine/shared/network_conn.cpp | 14 +++++++++++++ src/game/server/entities/character.cpp | 6 +++--- 6 files changed, 42 insertions(+), 24 deletions(-) diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index 690860e90..9898db059 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -1493,7 +1493,7 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket) if(Sys) { // system message - if(Msg == NETMSG_MAP_CHANGE) + if((pPacket->m_Flags&NET_CHUNKFLAG_VITAL) != 0 && Msg == NETMSG_MAP_CHANGE) { const char *pMap = Unpacker.GetString(CUnpacker::SANITIZE_CC|CUnpacker::SKIP_START_WHITESPACES); int MapCrc = Unpacker.GetInt(); @@ -1563,7 +1563,7 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket) } } } - else if(Msg == NETMSG_MAP_DATA) + else if((pPacket->m_Flags&NET_CHUNKFLAG_VITAL) != 0 && Msg == NETMSG_MAP_DATA) { int Last = Unpacker.GetInt(); int MapCRC = Unpacker.GetInt(); @@ -1602,7 +1602,7 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket) } } } - else if(Msg == NETMSG_CON_READY) + else if((pPacket->m_Flags&NET_CHUNKFLAG_VITAL) != 0 && Msg == NETMSG_CON_READY) { GameClient()->OnConnected(); } @@ -1611,7 +1611,7 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket) CMsgPacker Msg(NETMSG_PING_REPLY); SendMsgEx(&Msg, 0); } - else if(Msg == NETMSG_RCON_CMD_ADD) + else if((pPacket->m_Flags&NET_CHUNKFLAG_VITAL) != 0 && Msg == NETMSG_RCON_CMD_ADD) { const char *pName = Unpacker.GetString(CUnpacker::SANITIZE_CC); const char *pHelp = Unpacker.GetString(CUnpacker::SANITIZE_CC); @@ -1619,13 +1619,13 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket) if(Unpacker.Error() == 0) m_pConsole->RegisterTemp(pName, pParams, CFGFLAG_SERVER, pHelp); } - else if(Msg == NETMSG_RCON_CMD_REM) + else if((pPacket->m_Flags&NET_CHUNKFLAG_VITAL) != 0 && Msg == NETMSG_RCON_CMD_REM) { const char *pName = Unpacker.GetString(CUnpacker::SANITIZE_CC); if(Unpacker.Error() == 0) m_pConsole->DeregisterTemp(pName); } - else if(Msg == NETMSG_RCON_AUTH_STATUS) + else if((pPacket->m_Flags&NET_CHUNKFLAG_VITAL) != 0 && Msg == NETMSG_RCON_AUTH_STATUS) { int Result = Unpacker.GetInt(); if(Unpacker.Error() == 0) @@ -1637,7 +1637,7 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket) if(Old != 0 && m_UseTempRconCommands == 0) m_pConsole->DeregisterTempAll(); } - else if(Msg == NETMSG_RCON_LINE) + else if((pPacket->m_Flags&NET_CHUNKFLAG_VITAL) != 0 && Msg == NETMSG_RCON_LINE) { const char *pLine = Unpacker.GetString(); if(Unpacker.Error() == 0) @@ -1891,12 +1891,15 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket) } else { - // game message - for(int i = 0; i < RECORDER_MAX; i++) - if(m_DemoRecorder[i].IsRecording()) - m_DemoRecorder[i].RecordMessage(pPacket->m_pData, pPacket->m_DataSize); + if((pPacket->m_Flags&NET_CHUNKFLAG_VITAL) != 0) + { + // game message + for(int i = 0; i < RECORDER_MAX; i++) + if(m_DemoRecorder[i].IsRecording()) + m_DemoRecorder[i].RecordMessage(pPacket->m_pData, pPacket->m_DataSize); - GameClient()->OnMessage(Msg, &Unpacker); + GameClient()->OnMessage(Msg, &Unpacker); + } } } diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index c30c6b78f..1a2db2570 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -957,7 +957,7 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket) // system message if(Msg == NETMSG_INFO) { - if(m_aClients[ClientID].m_State == CClient::STATE_AUTH) + if((pPacket->m_Flags&NET_CHUNKFLAG_VITAL) != 0 && m_aClients[ClientID].m_State == CClient::STATE_AUTH) { const char *pVersion = Unpacker.GetString(CUnpacker::SANITIZE_CC); if(str_comp(pVersion, GameServer()->NetVersion()) != 0) @@ -990,8 +990,8 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket) } else if(Msg == NETMSG_REQUEST_MAP_DATA) { - if(m_aClients[ClientID].m_State < CClient::STATE_CONNECTING) - return; // no map w/o password, sorry guys + if((pPacket->m_Flags&NET_CHUNKFLAG_VITAL) == 0 || m_aClients[ClientID].m_State < CClient::STATE_CONNECTING) + return; int Chunk = Unpacker.GetInt(); unsigned int ChunkSize = 1024-128; @@ -1035,7 +1035,7 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket) } else if(Msg == NETMSG_READY) { - if(m_aClients[ClientID].m_State == CClient::STATE_CONNECTING) + if((pPacket->m_Flags&NET_CHUNKFLAG_VITAL) != 0 && m_aClients[ClientID].m_State == CClient::STATE_CONNECTING) { char aAddrStr[NETADDR_MAXSTRSIZE]; net_addr_str(m_NetServer.ClientAddr(ClientID), aAddrStr, sizeof(aAddrStr), true); @@ -1051,7 +1051,7 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket) } else if(Msg == NETMSG_ENTERGAME) { - if(m_aClients[ClientID].m_State == CClient::STATE_READY && GameServer()->IsClientReady(ClientID)) + if((pPacket->m_Flags&NET_CHUNKFLAG_VITAL) != 0 && m_aClients[ClientID].m_State == CClient::STATE_READY && GameServer()->IsClientReady(ClientID)) { char aAddrStr[NETADDR_MAXSTRSIZE]; net_addr_str(m_NetServer.ClientAddr(ClientID), aAddrStr, sizeof(aAddrStr), true); @@ -1124,7 +1124,7 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket) if (GameServer->m_apPlayers[ClientID] && GameServer->m_apPlayers[ClientID]->m_ClientVersion < VERSION_DDNET_OLD) GameServer->m_apPlayers[ClientID]->m_ClientVersion = VERSION_DDNET_OLD; } else - if(Unpacker.Error() == 0 && m_aClients[ClientID].m_Authed) + if((pPacket->m_Flags&NET_CHUNKFLAG_VITAL) != 0 && Unpacker.Error() == 0 && m_aClients[ClientID].m_Authed) { CGameContext *GameServer = (CGameContext *) m_pGameServer; if (GameServer->m_apPlayers[ClientID] && (GameServer->m_apPlayers[ClientID]->m_ClientVersion < VERSION_DDNET_RCONPROTECT || m_aClients[ClientID].m_LastAuthed)) @@ -1149,7 +1149,7 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket) Unpacker.GetString(); // login name, not used pPw = Unpacker.GetString(CUnpacker::SANITIZE_CC); - if(Unpacker.Error() == 0) + if((pPacket->m_Flags&NET_CHUNKFLAG_VITAL) != 0 && Unpacker.Error() == 0) { if(g_Config.m_SvRconPassword[0] == 0 && g_Config.m_SvRconModPassword[0] == 0) { @@ -1251,7 +1251,7 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket) else { // game message - if(m_aClients[ClientID].m_State >= CClient::STATE_READY) + if((pPacket->m_Flags&NET_CHUNKFLAG_VITAL) != 0 && m_aClients[ClientID].m_State >= CClient::STATE_READY) GameServer()->OnMessage(Msg, &Unpacker, ClientID); } } diff --git a/src/engine/shared/network.cpp b/src/engine/shared/network.cpp index c799c045c..fd9ba5ee3 100644 --- a/src/engine/shared/network.cpp +++ b/src/engine/shared/network.cpp @@ -83,7 +83,7 @@ int CNetRecvUnpacker::FetchChunk(CNetChunk *pChunk) // fill in the info pChunk->m_ClientID = m_ClientID; pChunk->m_Address = m_Addr; - pChunk->m_Flags = 0; + pChunk->m_Flags = Header.m_Flags; pChunk->m_DataSize = Header.m_Size; pChunk->m_pData = pData; return 1; diff --git a/src/engine/shared/network.h b/src/engine/shared/network.h index a9e7e642b..9834d2b84 100644 --- a/src/engine/shared/network.h +++ b/src/engine/shared/network.h @@ -153,6 +153,7 @@ class CNetConnection private: unsigned short m_Sequence; unsigned short m_Ack; + unsigned short m_PeerAck; unsigned m_State; int m_Token; diff --git a/src/engine/shared/network_conn.cpp b/src/engine/shared/network_conn.cpp index aa826d3e4..f52684b49 100644 --- a/src/engine/shared/network_conn.cpp +++ b/src/engine/shared/network_conn.cpp @@ -20,6 +20,7 @@ void CNetConnection::Reset(bool Rejoin) { m_Sequence = 0; m_Ack = 0; + m_PeerAck = 0; m_RemoteClosed = 0; if (!Rejoin) @@ -246,6 +247,19 @@ int CNetConnection::Feed(CNetPacketConstruct *pPacket, NETADDR *pAddr, SECURITY_ } } + // check if actual ack value is valid(own sequence..latest peer ack) + if(m_Sequence >= m_PeerAck) + { + if(pPacket->m_Ack < m_PeerAck || pPacket->m_Ack > m_Sequence) + return 0; + } + else + { + if(pPacket->m_Ack < m_PeerAck && pPacket->m_Ack > m_Sequence) + return 0; + } + m_PeerAck = pPacket->m_Ack; + int64 Now = time_get(); // check if resend is requested diff --git a/src/game/server/entities/character.cpp b/src/game/server/entities/character.cpp index 2b64aecb7..cd2b401df 100644 --- a/src/game/server/entities/character.cpp +++ b/src/game/server/entities/character.cpp @@ -476,7 +476,7 @@ void CCharacter::FireWeapon() for(unsigned i = 0; i < sizeof(CNetObj_Projectile)/sizeof(int); i++) Msg.AddInt(((int *)&p)[i]); - Server()->SendMsg(&Msg, 0, m_pPlayer->GetCID()); + Server()->SendMsg(&Msg, MSGFLAG_VITAL, m_pPlayer->GetCID()); GameServer()->CreateSound(m_Pos, SOUND_GUN_FIRE, Teams()->TeamMask(Team(), -1, m_pPlayer->GetCID())); } } break; @@ -510,7 +510,7 @@ void CCharacter::FireWeapon() Msg.AddInt(((int *)&p)[i]); } - Server()->SendMsg(&Msg, 0,m_pPlayer->GetCID()); + Server()->SendMsg(&Msg, MSGFLAG_VITAL, m_pPlayer->GetCID()); GameServer()->CreateSound(m_Pos, SOUND_SHOTGUN_FIRE);*/ float LaserReach; @@ -554,7 +554,7 @@ void CCharacter::FireWeapon() Msg.AddInt(1); for(unsigned i = 0; i < sizeof(CNetObj_Projectile)/sizeof(int); i++) Msg.AddInt(((int *)&p)[i]); - Server()->SendMsg(&Msg, 0, m_pPlayer->GetCID()); + Server()->SendMsg(&Msg, MSGFLAG_VITAL, m_pPlayer->GetCID()); GameServer()->CreateSound(m_Pos, SOUND_GRENADE_FIRE, Teams()->TeamMask(Team(), -1, m_pPlayer->GetCID())); } break;