From 993c2529c3f993c01910195da45b90e73282b4e0 Mon Sep 17 00:00:00 2001 From: lotodore Date: Thu, 18 Jun 2009 21:32:01 +0000 Subject: [PATCH] IP address bans are now time limited and will be removed automatically (minimum duration: 1 hour). --- src/net/common/serverbanmanager.cpp | 28 ++++++++++++++++++++++------ src/net/common/serverlobbythread.cpp | 2 +- src/net/common/servermanager.cpp | 14 +++++++++++--- src/net/serverbanmanager.h | 22 ++++++++++++++++++---- 4 files changed, 52 insertions(+), 14 deletions(-) diff --git a/src/net/common/serverbanmanager.cpp b/src/net/common/serverbanmanager.cpp index 6a7316d9..05638fbc 100644 --- a/src/net/common/serverbanmanager.cpp +++ b/src/net/common/serverbanmanager.cpp @@ -22,8 +22,8 @@ using namespace std; -ServerBanManager::ServerBanManager() -: m_curBanId(0) +ServerBanManager::ServerBanManager(boost::shared_ptr ioService) +: m_ioService(ioService), m_curBanId(0) { } @@ -39,10 +39,18 @@ ServerBanManager::BanPlayerRegex(const string &playerRegex) } void -ServerBanManager::BanIPAddress(const string &ipAddress) +ServerBanManager::BanIPAddress(const string &ipAddress, unsigned durationHours) { boost::mutex::scoped_lock lock(m_banMutex); - m_banIPAddressMap[GetNextBanId()] = ipAddress; + unsigned banId = GetNextBanId(); + boost::shared_ptr tmpItem(new TimedIPAddress(ipAddress, *m_ioService)); + tmpItem->timer.expires_from_now( + boost::posix_time::hours(durationHours)); + tmpItem->timer.async_wait( + boost::bind( + &ServerBanManager::TimerRemoveIPBan, shared_from_this(), boost::asio::placeholders::error, banId, tmpItem)); + + m_banIPAddressMap[banId] = tmpItem; } bool @@ -61,6 +69,7 @@ ServerBanManager::UnBan(unsigned banId) IPAddressMap::iterator posIP = m_banIPAddressMap.find(banId); if (posIP != m_banIPAddressMap.end()) { + posIP->second->timer.cancel(); m_banIPAddressMap.erase(posIP); retVal = true; } @@ -86,7 +95,7 @@ ServerBanManager::GetBanList(list &list) const while (i_ip != end_ip) { ostringstream banText; - banText << (*i_ip).first << ": (IP) - " << (*i_ip).second; + banText << (*i_ip).first << ": (IP) - " << (*i_ip).second->ipAddress << " duration: " << (*i_ip).second->timer.expires_from_now().hours() << "h"; list.push_back(banText.str()); ++i_ip; } @@ -129,7 +138,7 @@ ServerBanManager::IsIPAddressBanned(const std::string &ipAddress) const IPAddressMap::const_iterator end = m_banIPAddressMap.end(); while (i != end) { - if (ipAddress == (*i).second) + if (ipAddress == (*i).second->ipAddress) { retVal = true; break; @@ -140,6 +149,13 @@ ServerBanManager::IsIPAddressBanned(const std::string &ipAddress) const return retVal; } +void +ServerBanManager::TimerRemoveIPBan(const boost::system::error_code &ec, unsigned timerId, boost::shared_ptr item) +{ + if (!ec && item) + UnBan(timerId); +} + unsigned ServerBanManager::GetNextBanId() { diff --git a/src/net/common/serverlobbythread.cpp b/src/net/common/serverlobbythread.cpp index 2d5cc8fc..67f41a75 100644 --- a/src/net/common/serverlobbythread.cpp +++ b/src/net/common/serverlobbythread.cpp @@ -100,7 +100,7 @@ ServerLobbyThread::ServerLobbyThread(GuiInterface &gui, ConfigFile *playerConfig m_senderCallback.reset(new ServerSenderCallback(*this)); m_sender.reset(new SenderHelper(*m_senderCallback, m_ioService)); m_receiver.reset(new ReceiverHelper); - m_banManager.reset(new ServerBanManager); + m_banManager.reset(new ServerBanManager(m_ioService)); } ServerLobbyThread::~ServerLobbyThread() diff --git a/src/net/common/servermanager.cpp b/src/net/common/servermanager.cpp index a8e8f896..79d23b8c 100644 --- a/src/net/common/servermanager.cpp +++ b/src/net/common/servermanager.cpp @@ -141,11 +141,19 @@ ServerManager::SignalIrcChatMsg(const std::string &nickName, const std::string & { while (msgStream.peek() == ' ') msgStream.get(); - string ipAddress(msgStream.str().substr(msgStream.tellg())); + string ipAddress; + unsigned durationHours = 12; + msgStream >> ipAddress; + while (msgStream.peek() == ' ') + msgStream.get(); + if (!msgStream.eof()) + msgStream >> durationHours; if (!ipAddress.empty()) { - GetLobbyThread().GetBanManager().BanIPAddress(ipAddress); - m_ircThread->SendChatMessage(nickName + ": The IP address \"" + ipAddress + "\" was added to the IP address ban list."); + ostringstream durationStr; + durationStr << durationHours; + GetLobbyThread().GetBanManager().BanIPAddress(ipAddress, durationHours); + m_ircThread->SendChatMessage(nickName + ": The IP address \"" + ipAddress + "\" was added to the IP address ban list for " + durationStr.str() + (durationHours == 1 ? " hour." : " hours.")); } } else if (command == "listban") diff --git a/src/net/serverbanmanager.h b/src/net/serverbanmanager.h index c54c8cb6..cac8d9c8 100644 --- a/src/net/serverbanmanager.h +++ b/src/net/serverbanmanager.h @@ -23,17 +23,19 @@ #include #include +#include +#include #include #include -class ServerBanManager +class ServerBanManager : public boost::enable_shared_from_this { public: - ServerBanManager(); + ServerBanManager(boost::shared_ptr ioService); virtual ~ServerBanManager(); void BanPlayerRegex(const std::string &playerRegex); - void BanIPAddress(const std::string &ipAddress); + void BanIPAddress(const std::string &ipAddress, unsigned durationHours); bool UnBan(unsigned banId); void GetBanList(std::list &list) const; void ClearBanList(); @@ -42,8 +44,20 @@ public: bool IsIPAddressBanned(const std::string &ipAddress) const; protected: + struct TimedIPAddress + { + TimedIPAddress(const std::string &i, boost::asio::io_service &s) + : ipAddress(i), timer(s) {} + std::string ipAddress; + boost::asio::deadline_timer timer; + }; + + void TimerRemoveIPBan(const boost::system::error_code &ec, unsigned timerId, boost::shared_ptr item); + + boost::shared_ptr m_ioService; + typedef std::map RegexMap; - typedef std::map IPAddressMap; + typedef std::map > IPAddressMap; unsigned GetNextBanId();