int CNetServer::BanRemove(NETADDR Addr)
{
	int IpHash = (Addr.ip[0]+Addr.ip[1]+Addr.ip[2]+Addr.ip[3]+Addr.ip[4]+Addr.ip[5]+Addr.ip[6]+Addr.ip[7]+
					Addr.ip[8]+Addr.ip[9]+Addr.ip[10]+Addr.ip[11]+Addr.ip[12]+Addr.ip[13]+Addr.ip[14]+Addr.ip[15])&0xff;
	CBan *pBan = m_aBans[IpHash];

	MACRO_LIST_FIND(pBan, m_pHashNext, net_addr_comp(&pBan->m_Info.m_Addr, &Addr) == 0);

	if(pBan)
	{
		BanRemoveByObject(pBan);
		return 0;
	}

	return -1;
}
int CNetServer::Update()
{
	int Now = time_timestamp();
	for(int i = 0; i < MaxClients(); i++)
	{
		m_aSlots[i].m_Connection.Update();
		if(m_aSlots[i].m_Connection.State() == NET_CONNSTATE_ERROR)
			Drop(i, m_aSlots[i].m_Connection.ErrorString());
	}

	// remove expired bans
	while(m_BanPool_FirstUsed && m_BanPool_FirstUsed->m_Info.m_Expires > -1 && m_BanPool_FirstUsed->m_Info.m_Expires < Now)
	{
		CBan *pBan = m_BanPool_FirstUsed;
		BanRemoveByObject(pBan);
	}

	return 0;
}
Exemple #3
0
int CNetServer::BanAdd(NETADDR Addr, int Seconds, const char *pReason)
{
    int IpHash = (Addr.ip[0]+Addr.ip[1]+Addr.ip[2]+Addr.ip[3]+Addr.ip[4]+Addr.ip[5]+Addr.ip[6]+Addr.ip[7]+
                  Addr.ip[8]+Addr.ip[9]+Addr.ip[10]+Addr.ip[11]+Addr.ip[12]+Addr.ip[13]+Addr.ip[14]+Addr.ip[15])&0xff;
    int Stamp = -1;
    CBan *pBan;

    // remove the port
    Addr.port = 0;

    if(Seconds)
        Stamp = time_timestamp() + Seconds;

    // search to remove it if it already exists
    pBan = m_aBans[IpHash];
    MACRO_LIST_FIND(pBan, m_pHashNext, net_addr_comp(&pBan->m_Info.m_Addr, &Addr) == 0);
    if(pBan)
        BanRemoveByObject(pBan);

    if(!m_BanPool_FirstFree)
        return -1;

    // fetch and clear the new ban
    pBan = m_BanPool_FirstFree;
    MACRO_LIST_UNLINK(pBan, m_BanPool_FirstFree, m_pPrev, m_pNext);

    // setup the ban info
    pBan->m_Info.m_Expires = Stamp;
    pBan->m_Info.m_Addr = Addr;
    str_copy(pBan->m_Info.m_Reason, pReason, sizeof(pBan->m_Info.m_Reason));

    // add it to the ban hash
    MACRO_LIST_LINK_FIRST(pBan, m_aBans[IpHash], m_pHashPrev, m_pHashNext);

    // insert it into the used list
    {
        if(m_BanPool_FirstUsed)
        {
            CBan *pInsertAfter = m_BanPool_FirstUsed;
            MACRO_LIST_FIND(pInsertAfter, m_pNext, Stamp < pInsertAfter->m_Info.m_Expires);

            if(pInsertAfter && Stamp != -1)
                pInsertAfter = pInsertAfter->m_pPrev;
            else
            {
                // add to last
                if (m_BanPool_FirstUsed->m_Info.m_Expires == -1)
                    pInsertAfter = 0;
                else
                {
                    pInsertAfter = m_BanPool_FirstUsed;
                    while(pInsertAfter->m_pNext && pInsertAfter->m_pNext->m_Info.m_Expires != -1)
                        pInsertAfter = pInsertAfter->m_pNext;
                }
            }

            if(pInsertAfter)
            {
                MACRO_LIST_LINK_AFTER(pBan, pInsertAfter, m_pPrev, m_pNext);
            }
            else
            {
                MACRO_LIST_LINK_FIRST(pBan, m_BanPool_FirstUsed, m_pPrev, m_pNext);
            }
        }
        else
        {
            MACRO_LIST_LINK_FIRST(pBan, m_BanPool_FirstUsed, m_pPrev, m_pNext);
        }
    }

    // drop banned clients
    {
        char Buf[128];
        NETADDR BanAddr;

        if(Stamp > -1)
        {
            int Mins = (Seconds + 59) / 60;
            if(Mins <= 1)
                str_format(Buf, sizeof(Buf), "You have been banned for 1 minute (%s)", pReason);
            else
                str_format(Buf, sizeof(Buf), "You have been banned for %d minutes (%s)", Mins, pReason);
        }
        else
            str_format(Buf, sizeof(Buf), "You have been banned for life (%s)", pReason);

        for(int i = 0; i < MaxClients(); i++)
        {
            BanAddr = m_aSlots[i].m_Connection.PeerAddress();
            BanAddr.port = 0;

            if(net_addr_comp(&Addr, &BanAddr) == 0)
                Drop(i, Buf);
        }
    }
    return 0;
}