From 82f3734dd7eb430fdff903d1df4d8c322918f02d Mon Sep 17 00:00:00 2001 From: def Date: Wed, 31 Jul 2013 05:36:52 +0200 Subject: [PATCH 1/5] Try to implement netlimit (level too high, map downloads might fail) --- src/engine/shared/network.h | 8 ++++ src/engine/shared/network_server.cpp | 67 +++++++++++++++++++++++----- 2 files changed, 65 insertions(+), 10 deletions(-) diff --git a/src/engine/shared/network.h b/src/engine/shared/network.h index 80bd53c0a..3b370f1a5 100644 --- a/src/engine/shared/network.h +++ b/src/engine/shared/network.h @@ -249,9 +249,17 @@ class CNetServer CNetConnection m_Connection; }; + struct CTraffic + { + NETADDR m_Address; + int64 m_Traffic; + int64 m_TrafficSince; + }; + NETSOCKET m_Socket; class CNetBan *m_pNetBan; CSlot m_aSlots[NET_MAX_CLIENTS]; + CTraffic m_aTraffics[NET_MAX_CLIENTS]; int m_MaxClients; int m_MaxClientsPerIP; diff --git a/src/engine/shared/network_server.cpp b/src/engine/shared/network_server.cpp index f0aa6196b..730091f98 100644 --- a/src/engine/shared/network_server.cpp +++ b/src/engine/shared/network_server.cpp @@ -105,17 +105,64 @@ int CNetServer::Recv(CNetChunk *pChunk) if(Bytes <= 0) break; + // check if we just should drop the packet + char aBuf[128]; + if(NetBan() && NetBan()->IsBanned(&Addr, aBuf, sizeof(aBuf))) + { + // banned, reply with a message + CNetBase::SendControlMsg(m_Socket, &Addr, 0, NET_CTRLMSG_CLOSE, aBuf, str_length(aBuf)+1); + continue; + } + + bool Found = false; + bool Spam = false; + int64 Now = time_get(); + + for(int i = 0; i < MaxClients(); i++) + { + if (net_addr_comp(&m_aTraffics[i].m_Address, &Addr) == 0) + { + if (Now - m_aTraffics[i].m_TrafficSince > time_freq() * 5) + { + m_aTraffics[i].m_Traffic = 0; + m_aTraffics[i].m_TrafficSince = Now; + } + else + { + if ((Now - m_aTraffics[i].m_TrafficSince) / time_freq() > 0 && m_aTraffics[i].m_Traffic / ((Now - m_aTraffics[i].m_TrafficSince) / time_freq()) > 10000 /* * m_MaxClientsPerIP*/) + { + Spam = true; + break; + } + m_aTraffics[i].m_Traffic += Bytes; + } + Found = true; + break; + } + } + + if (Spam) + { + NetBan()->BanAddr(&Addr, 60, "Stressing network"); + continue; + } + + if (!Found) + { + for(int i = 0; i < MaxClients(); i++) + { + if (Now - m_aTraffics[i].m_TrafficSince > time_freq() * 5) + { + m_aTraffics[i].m_Address = Addr; + m_aTraffics[i].m_Traffic = 0; + m_aTraffics[i].m_TrafficSince = Now; + break; + } + } + } + if(CNetBase::UnpackPacket(m_RecvUnpacker.m_aBuffer, Bytes, &m_RecvUnpacker.m_Data) == 0) { - // check if we just should drop the packet - char aBuf[128]; - if(NetBan() && NetBan()->IsBanned(&Addr, aBuf, sizeof(aBuf))) - { - // banned, reply with a message - CNetBase::SendControlMsg(m_Socket, &Addr, 0, NET_CTRLMSG_CLOSE, aBuf, str_length(aBuf)+1); - continue; - } - if(m_RecvUnpacker.m_Data.m_Flags&NET_PACKETFLAG_CONNLESS) { pChunk->m_Flags = NETSENDFLAG_CONNLESS; @@ -130,7 +177,7 @@ int CNetServer::Recv(CNetChunk *pChunk) // TODO: check size here if(m_RecvUnpacker.m_Data.m_Flags&NET_PACKETFLAG_CONTROL && m_RecvUnpacker.m_Data.m_aChunkData[0] == NET_CTRLMSG_CONNECT) { - bool Found = false; + Found = false; // check if we already got this client for(int i = 0; i < MaxClients(); i++) From 71ba92313350d1703d2f633e3ca257ddd4fb828f Mon Sep 17 00:00:00 2001 From: def Date: Sun, 4 Aug 2013 04:24:03 +0200 Subject: [PATCH 2/5] Move netlimit over to regular server --- src/engine/server/server.cpp | 22 ++++++++++++++ src/engine/server/server.h | 3 ++ src/engine/shared/network.h | 8 ----- src/engine/shared/network_server.cpp | 45 ---------------------------- 4 files changed, 25 insertions(+), 53 deletions(-) diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index de49c9447..bd6741245 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -446,6 +446,8 @@ int CServer::Init() m_aClients[i].m_aClan[0] = 0; m_aClients[i].m_Country = -1; m_aClients[i].m_Snapshots.Init(); + m_aClients[i].m_Traffic = 0; + m_aClients[i].m_TrafficSince = 0; } m_CurrentGameTick = 0; @@ -843,6 +845,26 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket) if(Unpacker.Error()) return; + int64 Now = time_get(); + + if(Msg != NETMSG_REQUEST_MAP_DATA) + { + if (Now - m_aClients[ClientID].m_TrafficSince > time_freq() * 5) + { + m_aClients[ClientID].m_Traffic = 0; + m_aClients[ClientID].m_TrafficSince = Now; + } + else + { + if ((Now - m_aClients[ClientID].m_TrafficSince) / time_freq() > 0 && m_aClients[ClientID].m_Traffic / ((Now - m_aClients[ClientID].m_TrafficSince) / time_freq()) > 100000) + { + m_NetServer.NetBan()->BanAddr(&pPacket->m_Address, 60, "Stressing network"); + return; + } + m_aClients[ClientID].m_Traffic += pPacket->m_DataSize; + } + } + if(Sys) { // system message diff --git a/src/engine/server/server.h b/src/engine/server/server.h index 8c99e72e8..1b78ed263 100644 --- a/src/engine/server/server.h +++ b/src/engine/server/server.h @@ -118,6 +118,9 @@ public: int m_Latency; int m_SnapRate; + int64 m_Traffic; + int64 m_TrafficSince; + int m_LastAckedSnapshot; int m_LastInputTick; CSnapshotStorage m_Snapshots; diff --git a/src/engine/shared/network.h b/src/engine/shared/network.h index 3b370f1a5..80bd53c0a 100644 --- a/src/engine/shared/network.h +++ b/src/engine/shared/network.h @@ -249,17 +249,9 @@ class CNetServer CNetConnection m_Connection; }; - struct CTraffic - { - NETADDR m_Address; - int64 m_Traffic; - int64 m_TrafficSince; - }; - NETSOCKET m_Socket; class CNetBan *m_pNetBan; CSlot m_aSlots[NET_MAX_CLIENTS]; - CTraffic m_aTraffics[NET_MAX_CLIENTS]; int m_MaxClients; int m_MaxClientsPerIP; diff --git a/src/engine/shared/network_server.cpp b/src/engine/shared/network_server.cpp index 730091f98..0e0f5eda0 100644 --- a/src/engine/shared/network_server.cpp +++ b/src/engine/shared/network_server.cpp @@ -115,51 +115,6 @@ int CNetServer::Recv(CNetChunk *pChunk) } bool Found = false; - bool Spam = false; - int64 Now = time_get(); - - for(int i = 0; i < MaxClients(); i++) - { - if (net_addr_comp(&m_aTraffics[i].m_Address, &Addr) == 0) - { - if (Now - m_aTraffics[i].m_TrafficSince > time_freq() * 5) - { - m_aTraffics[i].m_Traffic = 0; - m_aTraffics[i].m_TrafficSince = Now; - } - else - { - if ((Now - m_aTraffics[i].m_TrafficSince) / time_freq() > 0 && m_aTraffics[i].m_Traffic / ((Now - m_aTraffics[i].m_TrafficSince) / time_freq()) > 10000 /* * m_MaxClientsPerIP*/) - { - Spam = true; - break; - } - m_aTraffics[i].m_Traffic += Bytes; - } - Found = true; - break; - } - } - - if (Spam) - { - NetBan()->BanAddr(&Addr, 60, "Stressing network"); - continue; - } - - if (!Found) - { - for(int i = 0; i < MaxClients(); i++) - { - if (Now - m_aTraffics[i].m_TrafficSince > time_freq() * 5) - { - m_aTraffics[i].m_Address = Addr; - m_aTraffics[i].m_Traffic = 0; - m_aTraffics[i].m_TrafficSince = Now; - break; - } - } - } if(CNetBase::UnpackPacket(m_RecvUnpacker.m_aBuffer, Bytes, &m_RecvUnpacker.m_Data) == 0) { From 7b2578b517df0c388f3caff4e0b3266187dec5c7 Mon Sep 17 00:00:00 2001 From: def Date: Sun, 4 Aug 2013 04:24:21 +0200 Subject: [PATCH 3/5] Only record when we're actually recording --- src/engine/server/server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index bd6741245..495878988 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -558,7 +558,7 @@ int CServer::SendMsgEx(CMsgPacker *pMsg, int Flags, int ClientID, bool System) Packet.m_Flags |= NETSENDFLAG_FLUSH; // write message to demo recorder - if(!(Flags&MSGFLAG_NORECORD)) + if(m_DemoRecorder.IsRecording() && !(Flags&MSGFLAG_NORECORD)) m_DemoRecorder.RecordMessage(pMsg->Data(), pMsg->Size()); if(!(Flags&MSGFLAG_NOSEND)) From da778f4e6617b1cae201d0c21bab364af70efe45 Mon Sep 17 00:00:00 2001 From: def Date: Sun, 4 Aug 2013 04:24:33 +0200 Subject: [PATCH 4/5] Don't write over memory limit... --- src/engine/shared/demo.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/engine/shared/demo.cpp b/src/engine/shared/demo.cpp index 37c82cce3..a6e2310db 100644 --- a/src/engine/shared/demo.cpp +++ b/src/engine/shared/demo.cpp @@ -183,6 +183,9 @@ void CDemoRecorder::Write(int Type, const void *pData, int Size) if(!m_File) return; + if(Size > 64*1024) + return; + /* pad the data with 0 so we get an alignment of 4, else the compression won't work and miss some bytes */ mem_copy(aBuffer2, pData, Size); From b51cc77189a0fa893542f25e1625b0bdcc48cd68 Mon Sep 17 00:00:00 2001 From: def Date: Sun, 4 Aug 2013 04:32:04 +0200 Subject: [PATCH 5/5] Add sv_netlimit --- src/engine/server/server.cpp | 2 +- src/engine/shared/config_variables.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 495878988..b4f63b8e9 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -856,7 +856,7 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket) } else { - if ((Now - m_aClients[ClientID].m_TrafficSince) / time_freq() > 0 && m_aClients[ClientID].m_Traffic / ((Now - m_aClients[ClientID].m_TrafficSince) / time_freq()) > 100000) + if ((Now - m_aClients[ClientID].m_TrafficSince) / time_freq() > 0 && m_aClients[ClientID].m_Traffic / ((Now - m_aClients[ClientID].m_TrafficSince) / time_freq()) > g_Config.m_SvNetlimit) { m_NetServer.NetBan()->BanAddr(&pPacket->m_Address, 60, "Stressing network"); return; diff --git a/src/engine/shared/config_variables.h b/src/engine/shared/config_variables.h index e9a401401..3443847ef 100644 --- a/src/engine/shared/config_variables.h +++ b/src/engine/shared/config_variables.h @@ -221,4 +221,7 @@ MACRO_CONFIG_INT(SvGlobalBantime, sv_global_ban_time, 60, 0, 1440, CFGFLAG_SERVE MACRO_CONFIG_INT(SvEvents, sv_events, 1, 0, 1, CFGFLAG_SERVER, "Enable triggering of server events, like the happy eyeemotes on some holidays.") +// netlimit +MACRO_CONFIG_INT(SvNetlimit, sv_netlimit, 10000, 1000, 1000000, CFGFLAG_SERVER, "Netlimit: Maximum amount of traffic a client is allowed to use (in kb/s)") + #endif