2020#include < pv/bitSetUtil.h>
2121#include < pv/standardPVField.h>
2222#include < pv/reftrack.h>
23+ #include < pv/sharedPtr.h>
2324
2425#define epicsExportSharedSymbols
2526#include < pv/pvAccess.h>
@@ -49,6 +50,9 @@ using std::tr1::static_pointer_cast;
4950using namespace std ;
5051using namespace epics ::pvData;
5152
53+ static const float maxBeaconLifetime = 180 .f * 2 .f;
54+ static const int maxTrackedBeacons = 20000 ;
55+
5256namespace epics {
5357namespace pvAccess {
5458
@@ -4338,6 +4342,36 @@ class InternalClientContextImpl :
43384342 m_channelSearchManager->newServerDetected ();
43394343 }
43404344
4345+ /* *
4346+ * Handles cleanup of old beacons.
4347+ */
4348+ class BeaconCleanupCallback : public TimerCallback
4349+ {
4350+ public:
4351+ typedef std::tr1::shared_ptr<BeaconCleanupCallback> shared_pointer;
4352+
4353+ BeaconCleanupCallback (InternalClientContextImpl& impl, osiSockAddr addr) :
4354+ m_from (addr),
4355+ m_impl (impl)
4356+ {
4357+ }
4358+
4359+ virtual void callback () OVERRIDE
4360+ {
4361+ Lock guard (m_impl.m_beaconMapMutex );
4362+ m_impl.m_beaconHandlers .erase (m_from);
4363+ }
4364+
4365+ virtual void timerStopped () OVERRIDE
4366+ {
4367+ this ->callback (); // Remove the beacon if the timer is closed.
4368+ }
4369+
4370+ private:
4371+ osiSockAddr m_from;
4372+ InternalClientContextImpl& m_impl;
4373+ };
4374+
43414375 /* *
43424376 * Get (and if necessary create) beacon handler.
43434377 * @param protocol the protocol.
@@ -4351,8 +4385,18 @@ class InternalClientContextImpl :
43514385 BeaconHandler::shared_pointer handler;
43524386 if (it == m_beaconHandlers.end ())
43534387 {
4388+ // If we're tracking too many beacons, we'll just ignore this one
4389+ if (m_beaconHandlers.size () >= maxTrackedBeacons)
4390+ {
4391+ char ipa[64 ];
4392+ sockAddrToDottedIP (&responseFrom->sa , ipa, sizeof (ipa));
4393+ LOG (logLevelDebug, " Tracked beacon limit reached (%d), ignoring %s\n " , maxTrackedBeacons, ipa);
4394+ return BeaconHandler::shared_pointer ();
4395+ }
4396+
43544397 // stores weak_ptr
43554398 handler.reset (new BeaconHandler (internal_from_this (), responseFrom));
4399+ m_timer->scheduleAfterDelay (BeaconCleanupCallback::shared_pointer (new BeaconCleanupCallback (*this , *responseFrom)), maxBeaconLifetime);
43564400 m_beaconHandlers[*responseFrom] = handler;
43574401 }
43584402 else
0 commit comments