Emit alerts for SIP and H.323 flood / local congestions.
Try to detect early the OpenH323 cleaner overload for outbound calls. git-svn-id: http://voip.null.ro/svn/yate@5627 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
parent
1887cf6a0e
commit
b23d7782cc
|
@ -245,6 +245,12 @@ static int cleaningCount()
|
|||
return s_connCount - s_chanCount;
|
||||
}
|
||||
|
||||
static bool cleaningBusy()
|
||||
{
|
||||
int maxc = s_maxCleaning;
|
||||
return (maxc > 0) && (cleaningCount() > maxc);
|
||||
}
|
||||
|
||||
class H323Process : public PProcess
|
||||
{
|
||||
PCLASSINFO(H323Process, PProcess)
|
||||
|
@ -870,6 +876,18 @@ static inline unsigned int threadIdleIntervals(u_int64_t periodUs)
|
|||
return (unsigned int)((periodUs + us - 1) / us);
|
||||
}
|
||||
|
||||
// Emit an alarm when refusing a new call but not more often than every 10s
|
||||
static void congestedWarn(const char* msg)
|
||||
{
|
||||
static uint64_t s_alarmTime = 0;
|
||||
if (s_alarmTime > Time::now())
|
||||
Debug(&hplugin,DebugWarn,"%s",msg);
|
||||
else {
|
||||
Alarm(&hplugin,"performance",DebugWarn,"%s",msg);
|
||||
s_alarmTime = Time::now() + 10000000;
|
||||
}
|
||||
}
|
||||
|
||||
// shameless adaptation from the G711 capability declaration
|
||||
#define DEFINE_YATE_CAPAB(cls,base,param,name) \
|
||||
class cls : public base { \
|
||||
|
@ -1010,7 +1028,7 @@ H323Connection* YateH323EndPoint::yateMakeCall(const PString& remoteParty,
|
|||
{
|
||||
// Sync with gatekeeper changing flag
|
||||
if (!startUsingGk(false)) {
|
||||
Debug(DebugWarn,"Refusing new outgoing H.323 call, gatekeeper busy");
|
||||
congestedWarn("Refusing new outgoing H.323 call, gatekeeper busy");
|
||||
return 0;
|
||||
}
|
||||
token = PString::Empty();
|
||||
|
@ -1025,21 +1043,18 @@ H323Connection* YateH323EndPoint::yateMakeCall(const PString& remoteParty,
|
|||
H323Connection* YateH323EndPoint::CreateConnection(unsigned callReference,
|
||||
void* userData, H323Transport* transport, H323SignalPDU* setupPDU)
|
||||
{
|
||||
if (s_maxCleaning > 0) {
|
||||
// check if there aren't too many connections assigned to the cleaner thread
|
||||
int cln = cleaningCount();
|
||||
if (cln > s_maxCleaning) {
|
||||
Debug(DebugWarn,"Refusing new H.323 call, there are already %d cleaning up",cln);
|
||||
return 0;
|
||||
}
|
||||
// check if there aren't too many connections assigned to the cleaner thread
|
||||
if (cleaningBusy()) {
|
||||
congestedWarn("Refusing new H.323 call, too many cleaning up");
|
||||
return 0;
|
||||
}
|
||||
if (!hplugin.canAccept(userData == 0)) {
|
||||
Debug(DebugWarn,"Refusing new H.323 call, full or exiting");
|
||||
congestedWarn("Refusing new H.323 call, full or exiting");
|
||||
return 0;
|
||||
}
|
||||
// Incoming call, sync with gatekeeper changing flag
|
||||
if (!userData && !startUsingGk(false)) {
|
||||
Debug(DebugWarn,"Refusing new incoming H.323 call, gatekeeper busy");
|
||||
congestedWarn("Refusing new incoming H.323 call, gatekeeper busy");
|
||||
return 0;
|
||||
}
|
||||
Lock mylock(this);
|
||||
|
@ -1689,6 +1704,11 @@ void YateGkRegThread::Main()
|
|||
// make a call either normally or in a proxy PWlib thread
|
||||
bool YateCallThread::makeCall(YateH323EndPoint* ep, const char* remoteParty, void* userData, bool newThread)
|
||||
{
|
||||
// check if there aren't too many connections assigned to the cleaner thread
|
||||
if (cleaningBusy()) {
|
||||
congestedWarn("Refusing new outgoing H.323 call, too many cleaning up");
|
||||
return false;
|
||||
}
|
||||
if (!newThread) {
|
||||
PString token;
|
||||
return ep->yateMakeCall(remoteParty,token,userData) != 0;
|
||||
|
|
|
@ -2930,12 +2930,18 @@ int YateSIPUDPTransport::process()
|
|||
b[res] = 0;
|
||||
if (s_printMsg)
|
||||
printRecvMsg(b,res);
|
||||
if (s_floodProtection && s_floodEvents && plugin.ep() && plugin.ep()->s_evCount >= s_floodEvents && !msgIsAllowed(b,res)) {
|
||||
if (Time::now() >= s_printFloodTime) {
|
||||
Debug(&plugin,DebugWarn,"Flood detected, dropping INVITE/REGISTER/SUBSCRIBE/OPTIONS messages, allowing reINVITES");
|
||||
s_printFloodTime = Time::now() + 10000000;
|
||||
}
|
||||
return 0;
|
||||
|
||||
if (s_floodProtection && s_floodEvents && evc >= s_floodEvents) {
|
||||
if (!s_printFloodTime)
|
||||
Alarm(&plugin,"performance",DebugWarn,
|
||||
"Flood detected, dropping INVITE/REGISTER/SUBSCRIBE/OPTIONS, allowing reINVITES");
|
||||
s_printFloodTime = Time::now() + 10000000;
|
||||
if (!msgIsAllowed(b,res))
|
||||
return 0;
|
||||
}
|
||||
else if (s_printFloodTime && s_printFloodTime < Time::now()) {
|
||||
s_printFloodTime = 0;
|
||||
Alarm(&plugin,"performance",DebugNote,"Flood drop cleared, resumed normal message processing");
|
||||
}
|
||||
|
||||
SIPMessage* msg = SIPMessage::fromParsing(0,b,res);
|
||||
|
|
Loading…
Reference in New Issue