From 2fe4636fa44ad48b801d0e38b892c0e47998327d Mon Sep 17 00:00:00 2001 From: brain Date: Mon, 8 Jan 2007 18:42:13 +0000 Subject: Add repeating timers, and make an hourly prune of the dns cache, otherwise a cache entry might not be cleared until a user with that ip comes back! git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@6264 e03df62e-2008-0410-955e-edbf42e46eb7 --- include/dns.h | 3 +++ include/timer.h | 26 ++++++++++++++++++++++++-- src/dns.cpp | 47 +++++++++++++++++++++++++++++++++++++++-------- src/timer.cpp | 32 ++++++++++++++++++++++++++------ 4 files changed, 92 insertions(+), 16 deletions(-) diff --git a/include/dns.h b/include/dns.h index 8011d069c..562a49322 100644 --- a/include/dns.h +++ b/include/dns.h @@ -326,6 +326,8 @@ class DNS : public EventHandler */ dnscache* cache; + class CacheTimer* PruneTimer; + /** * Build a dns packet payload */ @@ -450,6 +452,7 @@ class DNS : public EventHandler void DelCache(const std::string &source); int ClearCache(); + int PruneCache(); }; #endif diff --git a/include/timer.h b/include/timer.h index da8e742d9..f8e2bdcdf 100644 --- a/include/timer.h +++ b/include/timer.h @@ -30,12 +30,19 @@ class InspTimer : public Extensible /** The triggering time */ time_t trigger; + long secs; + bool repeat; public: /** Default constructor, initializes the triggering time + * @param secs_from_now The number of seconds from now to trigger the timer + * @param now The time now + * @param repeating Repeat this timer every secs_from_now seconds if set to true */ - InspTimer(long secs_from_now,time_t now) + InspTimer(long secs_from_now,time_t now, bool repeating = false) { trigger = now + secs_from_now; + secs = secs_from_now; + repeat = repeating; } /** Default destructor, does nothing. */ @@ -49,6 +56,16 @@ class InspTimer : public Extensible /** Called when the timer ticks. */ virtual void Tick(time_t TIME) = 0; + + bool GetRepeat() + { + return repeat; + } + + long GetSecs() + { + return secs; + } }; @@ -79,8 +96,13 @@ class TimerManager : public Extensible void TickTimers(time_t TIME); /** Add an InspTimer * @param T an InspTimer derived class to add + * @param secs_from_now You may set this to the number of seconds + * from the current time when the timer will tick, or you may just + * leave this unset and the values set by the InspTimers constructor + * will be used. This is used internally for re-triggering repeating + * timers. */ - void AddTimer(InspTimer* T); + void AddTimer(InspTimer* T, long secs_from_now = 0); /** Delete an InspTimer * @param T an InspTimer derived class to delete */ diff --git a/src/dns.cpp b/src/dns.cpp index cea1c4a43..625951ee5 100644 --- a/src/dns.cpp +++ b/src/dns.cpp @@ -103,6 +103,21 @@ class DNSRequest int SendRequests(const DNSHeader *header, const int length, QueryType qt); }; +class CacheTimer : public InspTimer +{ + private: + InspIRCd* ServerInstance; + DNS* dns; + public: + CacheTimer(InspIRCd* Instance, DNS* thisdns) + : InspTimer(3600, Instance->Time(), true), ServerInstance(Instance), dns(thisdns) { } + + virtual void Tick(time_t TIME) + { + dns->PruneCache(); + } +}; + class RequestTimeout : public InspTimer { InspIRCd* ServerInstance; @@ -262,6 +277,23 @@ int DNS::ClearCache() return rv; } +int DNS::PruneCache() +{ + int n = 0; + dnscache* newcache = new dnscache(); + for (dnscache::iterator i = this->cache->begin(); i != this->cache->end(); i++) + /* Dont include expired items (theres no point) */ + if (i->second.CalcTTLRemaining()) + newcache->insert(*i); + else + n++; + + delete this->cache; + this->cache = newcache; + ServerInstance->Log(DEBUG,"Prune %d expired cache items", n); + return n; +} + void DNS::Rehash() { insp_inaddr addr; @@ -276,14 +308,7 @@ void DNS::Rehash() this->SetFd(-1); /* Rehash the cache */ - dnscache* newcache = new dnscache(); - for (dnscache::iterator i = this->cache->begin(); i != this->cache->end(); i++) - /* Dont include expired items (theres no point) */ - if (i->second.CalcTTLRemaining()) - newcache->insert(*i); - - delete this->cache; - this->cache = newcache; + this->PruneCache(); } else { @@ -397,6 +422,10 @@ DNS::DNS(InspIRCd* Instance) : ServerInstance(Instance) /* Actually read the settings */ this->Rehash(); + + this->PruneTimer = new CacheTimer(ServerInstance, this); + + ServerInstance->Timers->AddTimer(this->PruneTimer); } /** Build a payload to be placed after the header, based upon input data, a resource type, a class and a pointer to a buffer */ @@ -906,6 +935,8 @@ DNS::~DNS() { shutdown(this->GetFd(), 2); close(this->GetFd()); + ServerInstance->Timers->DelTimer(this->PruneTimer); + delete this->PruneTimer; } CachedQuery* DNS::GetCache(const std::string &source) diff --git a/src/timer.cpp b/src/timer.cpp index 04ff1c15b..6be7aa06c 100644 --- a/src/timer.cpp +++ b/src/timer.cpp @@ -28,7 +28,14 @@ void TimerManager::TickTimers(time_t TIME) { InspTimer* n = *y; n->Tick(TIME); - DELETE(n); + if (n->GetRepeat()) + { + AddTimer(n, n->GetSecs()); + } + else + { + DELETE(n); + } } Timers.erase(found); @@ -78,7 +85,14 @@ void TimerManager::TickMissedTimers(time_t TIME) { InspTimer* z = *y; z->Tick(TIME); - DELETE(z); + if (z->GetRepeat()) + { + AddTimer(z, z->GetSecs()); + } + else + { + DELETE(z); + } } Timers.erase(found); @@ -87,12 +101,18 @@ void TimerManager::TickMissedTimers(time_t TIME) } } -void TimerManager::AddTimer(InspTimer* T) +void TimerManager::AddTimer(InspTimer* T, long secs_from_now) { timergroup* x = NULL; - timerlist::iterator found = Timers.find(T->GetTimer()); - + int time_to_trigger = 0; + if (!secs_from_now) + time_to_trigger = T->GetTimer(); + else + time_to_trigger = secs_from_now + time(NULL); + + timerlist::iterator found = Timers.find(time_to_trigger); + if (found != Timers.end()) { x = found->second; @@ -100,7 +120,7 @@ void TimerManager::AddTimer(InspTimer* T) else { x = new timergroup; - Timers[T->GetTimer()] = x; + Timers[time_to_trigger] = x; } x->push_back(T); -- cgit v1.2.3