1337: Ignore DNSBL on "empty" servers. r=heinrich5991 a=Learath2

DNSBL is to prevent annoyances. There is no one to annoy on an empty server.

Co-authored-by: Learath <learath2@gmail.com>
This commit is contained in:
bors[bot] 2018-10-08 18:38:28 +00:00
commit 1f4585c335
11 changed files with 109 additions and 59 deletions

View file

@ -997,6 +997,14 @@ int net_addr_comp(const NETADDR *a, const NETADDR *b)
return mem_comp(a, b, sizeof(NETADDR));
}
int net_addr_comp_noport(const NETADDR *a, const NETADDR *b)
{
NETADDR ta = *a, tb = *b;
ta.port = tb.port = 0;
return net_addr_comp(&ta, &tb);
}
void net_addr_str(const NETADDR *addr, char *string, int max_length, int add_port)
{
if(addr->type == NETTYPE_IPV4 || addr->type == NETTYPE_WEBSOCKET_IPV4)

View file

@ -149,7 +149,7 @@ void mem_zero(void *block, unsigned size);
size - Size of the data to compare
Returns:
<0 - Block a is lesser then block b
<0 - Block a is lesser than block b
0 - Block a is equal to block b
>0 - Block a is greater than block b
*/
@ -666,12 +666,27 @@ int net_host_lookup(const char *hostname, NETADDR *addr, int types);
b - Address to compare to.
Returns:
<0 - Address a is lesser then address b
<0 - Address a is lesser than address b
0 - Address a is equal to address b
>0 - Address a is greater then address b
>0 - Address a is greater than address b
*/
int net_addr_comp(const NETADDR *a, const NETADDR *b);
/*
Function: net_addr_comp_noport
Compares two network addresses ignoring port.
Parameters:
a - Address to compare
b - Address to compare to.
Returns:
<0 - Address a is lesser than address b
0 - Address a is equal to address b
>0 - Address a is greater than address b
*/
int net_addr_comp_noport(const NETADDR *a, const NETADDR *b);
/*
Function: net_addr_str
Turns a network address into a representative string.
@ -1077,9 +1092,9 @@ char *str_skip_whitespaces(char *str);
b - String to compare.
Returns:
<0 - String a is lesser then string b
<0 - String a is lesser than string b
0 - String a is equal to string b
>0 - String a is greater then string b
>0 - String a is greater than string b
Remarks:
- Only garanted to work with a-z/A-Z.
@ -1116,9 +1131,9 @@ int str_comp_nocase_num(const char *a, const char *b, const int num);
b - String to compare.
Returns:
<0 - String a is lesser then string b
<0 - String a is lesser than string b
0 - String a is equal to string b
>0 - String a is greater then string b
>0 - String a is greater than string b
Remarks:
- The strings are treated as zero-terminated strings.
@ -1135,9 +1150,9 @@ int str_comp(const char *a, const char *b);
num - Maximum characters to compare
Returns:
<0 - String a is lesser then string b
<0 - String a is lesser than string b
0 - String a is equal to string b
>0 - String a is greater then string b
>0 - String a is greater than string b
Remarks:
- The strings are treated as zero-terminated strings.
@ -1153,9 +1168,9 @@ int str_comp_num(const char *a, const char *b, const int num);
b - String to compare.
Returns:
<0 - String a is lesser then string b
<0 - String a is lesser than string b
0 - String a is equal to string b
>0 - String a is greater then string b
>0 - String a is greater than string b
Remarks:
- The strings are treated as zero-terminated strings.

View file

@ -32,6 +32,8 @@ public:
int TickSpeed() const { return m_TickSpeed; }
virtual int MaxClients() const = 0;
virtual int ClientCount() = 0;
virtual int DistinctClientCount() = 0;
virtual const char *ClientName(int ClientID) = 0;
virtual const char *ClientClan(int ClientID) = 0;
virtual int ClientCountry(int ClientID) = 0;

View file

@ -239,13 +239,9 @@ int CRegister::RegisterProcessPacket(CNetChunk *pPacket)
{
// check for masterserver address
bool Valid = false;
NETADDR Addr1 = pPacket->m_Address;
Addr1.port = 0;
for(int i = 0; i < IMasterServer::MAX_MASTERSERVERS; i++)
{
NETADDR Addr2 = m_aMasterserverInfo[i].m_Addr;
Addr2.port = 0;
if(net_addr_comp(&Addr1, &Addr2) == 0)
if(net_addr_comp_noport(&pPacket->m_Address, &m_aMasterserverInfo[i].m_Addr) == 0)
{
Valid = true;
break;

View file

@ -554,6 +554,51 @@ int CServer::MaxClients() const
return m_NetServer.MaxClients();
}
int CServer::ClientCount()
{
int ClientCount = 0;
for(int i = 0; i < MAX_CLIENTS; i++)
{
if(m_aClients[i].m_State != CClient::STATE_EMPTY)
{
ClientCount++;
}
}
return ClientCount;
}
int CServer::DistinctClientCount()
{
NETADDR aAddresses[MAX_CLIENTS];
for(int i = 0; i < MAX_CLIENTS; i++)
{
if(m_aClients[i].m_State != CClient::STATE_EMPTY)
{
GetClientAddr(i, &aAddresses[i]);
}
}
int ClientCount = 0;
for(int i = 0; i < MAX_CLIENTS; i++)
{
if(m_aClients[i].m_State != CClient::STATE_EMPTY)
{
ClientCount++;
for(int j = 0; j < i; j++)
{
if(!net_addr_comp_noport(&aAddresses[i], &aAddresses[j]))
{
ClientCount--;
break;
}
}
}
}
return ClientCount;
}
int CServer::SendMsg(CMsgPacker *pMsg, int Flags, int ClientID)
{
return SendMsgEx(pMsg, Flags, ClientID, false);
@ -1900,7 +1945,7 @@ int CServer::Run()
char aBuf[256];
str_format(aBuf, sizeof(aBuf), "ClientID=%d addr=%s secure=%s blacklisted", ClientID, aAddrStr, m_NetServer.HasSecurityToken(ClientID)?"yes":"no");
Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "dnsbl", aBuf);
}
}
@ -2341,7 +2386,7 @@ void CServer::ConNameBan(IConsole::IResult *pResult, void *pUser)
{
Distance = str_length(pName) / 3;
}
for(int i = 0; i < pThis->m_aNameBans.size(); i++)
{
CNameBan *pBan = &pThis->m_aNameBans[i];

View file

@ -260,6 +260,8 @@ public:
bool ClientIngame(int ClientID);
bool ClientAuthed(int ClientID);
int MaxClients() const;
int ClientCount();
int DistinctClientCount();
virtual int SendMsg(CMsgPacker *pMsg, int Flags, int ClientID);
int SendMsgEx(CMsgPacker *pMsg, int Flags, int ClientID, bool System);

View file

@ -312,12 +312,8 @@ int CNetConnection::Feed(CNetPacketConstruct *pPacket, NETADDR *pAddr, SECURITY_
{
if(CtrlMsg == NET_CTRLMSG_CONNECT)
{
NETADDR nAddr;
mem_copy(&nAddr, pAddr, sizeof(nAddr));
nAddr.port = 0;
m_PeerAddr.port = 0;
#ifndef FUZZING
if(net_addr_comp(&m_PeerAddr, &nAddr) == 0 && time_get() - m_LastUpdateTime < time_freq() * 3)
if(net_addr_comp_noport(&m_PeerAddr, pAddr) == 0 && time_get() - m_LastUpdateTime < time_freq() * 3)
return 0;
#endif

View file

@ -168,11 +168,7 @@ void CNetServer::SendControl(NETADDR &Addr, int ControlMsg, const void *pExtra,
int CNetServer::NumClientsWithAddr(NETADDR Addr)
{
NETADDR ThisAddr = Addr, OtherAddr;
int FoundAddr = 0;
ThisAddr.port = 0;
for(int i = 0; i < MaxClients(); ++i)
{
if(m_aSlots[i].m_Connection.State() == NET_CONNSTATE_OFFLINE ||
@ -181,9 +177,7 @@ int CNetServer::NumClientsWithAddr(NETADDR Addr)
!m_aSlots[i].m_Connection.m_TimeoutSituation)))
continue;
OtherAddr = *m_aSlots[i].m_Connection.PeerAddress();
OtherAddr.port = 0;
if(!net_addr_comp(&ThisAddr, &OtherAddr))
if(!net_addr_comp_noport(&Addr, m_aSlots[i].m_Connection.PeerAddress()))
FoundAddr++;
}

View file

@ -345,18 +345,15 @@ void CGameContext::ConForcePause(IConsole::IResult *pResult, void *pUserData)
pPlayer->ForcePause(Seconds);
}
void CGameContext::VoteMute(IConsole::IResult *pResult, NETADDR *pAddr, int Secs,
const char *pDisplayName, int AuthedID)
void CGameContext::VoteMute(const NETADDR *pAddr, int Secs, const char *pDisplayName, int AuthedID)
{
char aBuf[128];
bool Found = 0;
pAddr->port = 0; // ignore port number for vote mutes
// find a matching vote mute for this ip, update expiration time if found
for(int i = 0; i < m_NumVoteMutes; i++)
{
if(net_addr_comp(&m_aVoteMutes[i].m_Addr, pAddr) == 0)
if(net_addr_comp_noport(&m_aVoteMutes[i].m_Addr, pAddr) == 0)
{
m_aVoteMutes[i].m_Expire = Server()->Tick()
+ Secs * Server()->TickSpeed();
@ -389,18 +386,15 @@ void CGameContext::VoteMute(IConsole::IResult *pResult, NETADDR *pAddr, int Secs
Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "votemute", "vote mute array is full");
}
void CGameContext::Mute(IConsole::IResult *pResult, NETADDR *Addr, int Secs,
const char *pDisplayName)
void CGameContext::Mute(const NETADDR *pAddr, int Secs, const char *pDisplayName)
{
char aBuf[128];
int Found = 0;
Addr->port = 0; // ignore port number for mutes
// find a matching mute for this ip, update expiration time if found
for (int i = 0; i < m_NumMutes; i++)
{
if (net_addr_comp(&m_aMutes[i].m_Addr, Addr) == 0)
if (net_addr_comp_noport(&m_aMutes[i].m_Addr, pAddr) == 0)
{
m_aMutes[i].m_Expire = Server()->Tick()
+ Secs * Server()->TickSpeed();
@ -412,7 +406,7 @@ void CGameContext::Mute(IConsole::IResult *pResult, NETADDR *Addr, int Secs,
{
if (m_NumMutes < MAX_MUTES)
{
m_aMutes[m_NumMutes].m_Addr = *Addr;
m_aMutes[m_NumMutes].m_Addr = *pAddr;
m_aMutes[m_NumMutes].m_Expire = Server()->Tick()
+ Secs * Server()->TickSpeed();
m_NumMutes++;
@ -446,7 +440,7 @@ void CGameContext::ConVoteMute(IConsole::IResult *pResult, void *pUserData)
NETADDR Addr;
pSelf->Server()->GetClientAddr(Victim, &Addr);
pSelf->VoteMute(pResult, &Addr, clamp(pResult->GetInteger(1), 1, 86400),
pSelf->VoteMute(&Addr, clamp(pResult->GetInteger(1), 1, 86400),
pSelf->Server()->ClientName(Victim), pResult->m_ClientID);
}
@ -464,7 +458,7 @@ void CGameContext::ConMuteID(IConsole::IResult *pResult, void *pUserData)
{
CGameContext *pSelf = (CGameContext *) pUserData;
int Victim = pResult->GetVictim();
if (Victim < 0 || Victim > MAX_CLIENTS || !pSelf->m_apPlayers[Victim])
{
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "muteid", "Client id not found.");
@ -474,7 +468,7 @@ void CGameContext::ConMuteID(IConsole::IResult *pResult, void *pUserData)
NETADDR Addr;
pSelf->Server()->GetClientAddr(Victim, &Addr);
pSelf->Mute(pResult, &Addr, clamp(pResult->GetInteger(1), 1, 86400),
pSelf->Mute(&Addr, clamp(pResult->GetInteger(1), 1, 86400),
pSelf->Server()->ClientName(Victim));
}
@ -488,7 +482,7 @@ void CGameContext::ConMuteIP(IConsole::IResult *pResult, void *pUserData)
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "mutes",
"Invalid network address to mute");
}
pSelf->Mute(pResult, &Addr, clamp(pResult->GetInteger(1), 1, 86400), NULL);
pSelf->Mute(&Addr, clamp(pResult->GetInteger(1), 1, 86400), NULL);
}
// unmute by mute list index
@ -514,7 +508,7 @@ void CGameContext::ConUnmute(IConsole::IResult *pResult, void *pUserData)
void CGameContext::ConMutes(IConsole::IResult *pResult, void *pUserData)
{
CGameContext *pSelf = (CGameContext *) pUserData;
if (pSelf->m_NumMutes <= 0)
{
// Just to make sure.
@ -523,7 +517,7 @@ void CGameContext::ConMutes(IConsole::IResult *pResult, void *pUserData)
"There are no active mutes.");
return;
}
char aIpBuf[64];
char aBuf[128];
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "mutes",
@ -563,7 +557,7 @@ void CGameContext::ConModerate(IConsole::IResult *pResult, void *pUserData)
str_format(aBuf, sizeof(aBuf), "Server kick/spec votes are no longer actively moderated.");
pSelf->SendChat(-1, CHAT_ALL, aBuf, 0);
if(pPlayer->m_Moderating)
pSelf->SendChatTarget(pResult->m_ClientID, "Active moderator mode enabled for you.");
else
@ -636,6 +630,6 @@ void CGameContext::ConUnFreezeHammer(IConsole::IResult *pResult, void *pUserData
void CGameContext::ConVoteNo(IConsole::IResult *pResult, void *pUserData)
{
CGameContext *pSelf = (CGameContext *)pUserData;
pSelf->ForceVote(pResult->m_ClientID, false);
}

View file

@ -1340,7 +1340,7 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID)
return;
}
if (g_Config.m_SvDnsblVote && !m_pServer->DnsblWhite(ClientID))
if (g_Config.m_SvDnsblVote && !m_pServer->DnsblWhite(ClientID) && Server()->DistinctClientCount() > 1)
{
// blacklisted by dnsbl
SendChatTarget(ClientID, "You are not allowed to vote due to DNSBL.");
@ -1382,10 +1382,9 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID)
NETADDR Addr;
Server()->GetClientAddr(ClientID, &Addr);
Addr.port = 0; // ignore port number
int VoteMuted = 0;
for(int i = 0; i < m_NumVoteMutes && !VoteMuted; i++)
if(!net_addr_comp(&Addr, &m_aVoteMutes[i].m_Addr))
if(!net_addr_comp_noport(&Addr, &m_aVoteMutes[i].m_Addr))
VoteMuted = (m_aVoteMutes[i].m_Expire - Server()->Tick()) / Server()->TickSpeed();
if(VoteMuted > 0)
{
@ -3280,12 +3279,11 @@ int CGameContext::ProcessSpamProtection(int ClientID)
m_apPlayers[ClientID]->m_LastChat = Server()->Tick();
NETADDR Addr;
Server()->GetClientAddr(ClientID, &Addr);
Addr.port = 0; // ignore port number for mutes
int Muted = 0;
for(int i = 0; i < m_NumMutes && !Muted; i++)
{
if(!net_addr_comp(&Addr, &m_aMutes[i].m_Addr))
if(!net_addr_comp_noport(&Addr, &m_aMutes[i].m_Addr))
Muted = (m_aMutes[i].m_Expire - Server()->Tick()) / Server()->TickSpeed();
}
@ -3299,7 +3297,7 @@ int CGameContext::ProcessSpamProtection(int ClientID)
if ((m_apPlayers[ClientID]->m_ChatScore += g_Config.m_SvChatPenalty) > g_Config.m_SvChatThreshold)
{
Mute(0, &Addr, g_Config.m_SvSpamMuteDuration, Server()->ClientName(ClientID));
Mute(&Addr, g_Config.m_SvSpamMuteDuration, Server()->ClientName(ClientID));
m_apPlayers[ClientID]->m_ChatScore = 0;
return 1;
}
@ -3568,10 +3566,10 @@ void CGameContext::ForceVote(int EnforcerID, bool Success)
// check if there is a vote running
if(!m_VoteCloseTime)
return;
m_VoteEnforce = Success ? CGameContext::VOTE_ENFORCE_YES_ADMIN : CGameContext::VOTE_ENFORCE_NO_ADMIN;
m_VoteEnforcer = EnforcerID;
char aBuf[256];
const char *pOption = Success ? "yes" : "no";
str_format(aBuf, sizeof(aBuf), "authorized player forced vote %s", pOption);

View file

@ -384,8 +384,8 @@ private:
int m_NumMutes;
CVoteMute m_aVoteMutes[MAX_VOTE_BANS];
int m_NumVoteMutes;
void Mute(IConsole::IResult *pResult, NETADDR *Addr, int Secs, const char *pDisplayName);
void VoteMute(IConsole::IResult *pResult, NETADDR *pAddr, int Secs, const char *pDisplayName, int AuthedID);
void Mute(const NETADDR *pAddr, int Secs, const char *pDisplayName);
void VoteMute(const NETADDR *pAddr, int Secs, const char *pDisplayName, int AuthedID);
void Whisper(int ClientID, char *pStr);
void WhisperID(int ClientID, int VictimID, char *pMessage);
void Converse(int ClientID, char *pStr);