Пример #1
0
int netserver_ban_add(NETSERVER *s, NETADDR addr, int seconds)
{
	int iphash = (addr.ip[0]+addr.ip[1]+addr.ip[2]+addr.ip[3])&0xff;
	unsigned stamp = 0xffffffff;
	NETBAN *ban;
	
	/* remove the port */
	addr.port = 0;
	
	if(seconds)
		stamp = time_timestamp() + seconds;
		
	/* search to see if it already exists */
	ban = s->bans[iphash];
	MACRO_LIST_FIND(ban, hashnext, net_addr_comp(&ban->info.addr, &addr) == 0);
	if(ban)
	{
		/* adjust the ban */
		ban->info.expires = stamp;
		return 0;
	}
	
	if(!s->banpool_firstfree)
		return -1;

	/* fetch and clear the new ban */
	ban = s->banpool_firstfree;
	MACRO_LIST_UNLINK(ban, s->banpool_firstfree, prev, next);
	
	/* setup the ban info */
	ban->info.expires = stamp;
	ban->info.addr = addr;
	
	/* add it to the ban hash */
	MACRO_LIST_LINK_FIRST(ban, s->bans[iphash], hashprev, hashnext);
	
	/* insert it into the used list */
	{
		if(s->banpool_firstused)
		{
			NETBAN *insert_after = s->banpool_firstused;
			MACRO_LIST_FIND(insert_after, next, stamp < insert_after->info.expires);
			
			if(insert_after)
				insert_after = insert_after->prev;
			else
			{
				/* add to last */
				insert_after = s->banpool_firstused;
				while(insert_after->next)
					insert_after = insert_after->next;
			}
			
			if(insert_after)
			{
				MACRO_LIST_LINK_AFTER(ban, insert_after, prev, next);
			}
			else
			{
				MACRO_LIST_LINK_FIRST(ban, s->banpool_firstused, prev, next);
			}
		}
		else
		{
			MACRO_LIST_LINK_FIRST(ban, s->banpool_firstused, prev, next);
		}
	}

	/* drop banned clients */	
	{
		char buf[128];
		int i;
		NETADDR banaddr;
		
		if(seconds)
			str_format(buf, sizeof(buf), "you have been banned for %d minutes", seconds/60);
		else
			str_format(buf, sizeof(buf), "you have been banned for life");
		
		for(i = 0; i < s->max_clients; i++)
		{
			banaddr = s->slots[i].conn.peeraddr;
			banaddr.port = 0;
			
			if(net_addr_comp(&addr, &banaddr) == 0)
				netserver_drop(s, i, buf);
		}
	}
	return 0;
}
Пример #2
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 see 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)
	{
		// adjust the ban
		pBan->m_Info.m_Expires = Stamp;
		return 0;
	}

	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)
				pInsertAfter = pInsertAfter->m_pPrev;
			else
			{
				// add to last
				pInsertAfter = m_BanPool_FirstUsed;
				while(pInsertAfter->m_pNext)
					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;
}