Skip to content

Commit afca135

Browse files
committed
clientContextImpl: Cap the number and age of beacons
Each beacon has an associated mutex. If we allocate too many beacons on resource constrained systems, i.e. RTEMS, we may run out of resources and crash.
1 parent cf483d6 commit afca135

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed

src/remoteClient/clientContextImpl.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ using std::tr1::static_pointer_cast;
4949
using namespace std;
5050
using namespace epics::pvData;
5151

52+
static const float maxBeaconLifetime = 180.f * 2.f;
53+
static const int maxTrackedBeacons = 20000;
54+
5255
namespace epics {
5356
namespace pvAccess {
5457

@@ -4338,6 +4341,34 @@ class InternalClientContextImpl :
43384341
m_channelSearchManager->newServerDetected();
43394342
}
43404343

4344+
/**
4345+
* Handles cleanup of old beacons.
4346+
*/
4347+
class BeaconCleanupCallback : public TimerCallback
4348+
{
4349+
public:
4350+
BeaconCleanupCallback(InternalClientContextImpl& impl, osiSockAddr addr) :
4351+
m_from(addr),
4352+
m_impl(impl)
4353+
{
4354+
}
4355+
4356+
virtual void callback() OVERRIDE
4357+
{
4358+
Lock guard(m_impl.m_beaconMapMutex);
4359+
m_impl.m_beaconHandlers.erase(m_from);
4360+
}
4361+
4362+
virtual void timerStopped() OVERRIDE
4363+
{
4364+
this->callback(); // Remove the beacon if the timer is closed.
4365+
}
4366+
4367+
private:
4368+
osiSockAddr m_from;
4369+
InternalClientContextImpl& m_impl;
4370+
};
4371+
43414372
/**
43424373
* Get (and if necessary create) beacon handler.
43434374
* @param protocol the protocol.
@@ -4351,8 +4382,18 @@ class InternalClientContextImpl :
43514382
BeaconHandler::shared_pointer handler;
43524383
if (it == m_beaconHandlers.end())
43534384
{
4385+
// If we're tracking too many beacons, we'll just ignore this one
4386+
if (m_beaconHandlers.size() >= maxTrackedBeacons)
4387+
{
4388+
char ipa[64];
4389+
sockAddrToDottedIP(&responseFrom->sa, ipa, sizeof(ipa));
4390+
LOG(logLevelDebug, "Tracked beacon limit reached (%d), ignoring %s\n", maxTrackedBeacons, ipa);
4391+
return nullptr;
4392+
}
4393+
43544394
// stores weak_ptr
43554395
handler.reset(new BeaconHandler(internal_from_this(), responseFrom));
4396+
m_timer->scheduleAfterDelay(std::make_shared<BeaconCleanupCallback>(*this, *responseFrom), maxBeaconLifetime);
43564397
m_beaconHandlers[*responseFrom] = handler;
43574398
}
43584399
else

0 commit comments

Comments
 (0)