Added gatekeeper discovery retry and reregistration.

git-svn-id: http://yate.null.ro/svn/yate/trunk@514 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
paulc 2005-09-16 10:36:43 +00:00
parent e8bacc3eb8
commit 50fcb28831
2 changed files with 91 additions and 28 deletions

View File

@ -127,6 +127,13 @@ gkclient = false
; gkname: string: Set the name of the gatekeeper ; gkname: string: Set the name of the gatekeeper
;gkname = gigi ;gkname = gigi
; gkttl: int: Proposed gatekeeper registration time to live in seconds
;gkttl = 300
; gkretry: int: Gatekeeper discovery retry interval in seconds, 0 disables
;gkretry = 60
; How the gatekeeper is located ; How the gatekeeper is located
; If gkclient is true the endpoint will try first to find the gatekeeper by ; If gkclient is true the endpoint will try first to find the gatekeeper by
; using gkip; then, if gkip is unset or is not corect, will try gkname and ; using gkip; then, if gkip is unset or is not corect, will try gkname and
@ -145,13 +152,25 @@ gkclient = false
; whatever you use) and then just dial the number. ; whatever you use) and then just dial the number.
; If you wanna call a registered endpoint you must use now as a module register ; If you wanna call a registered endpoint you must use now as a module register
; since is the only module who can record prefixes right now. ; since is the only module who can record prefixes right now.
server=false
; You must define the binding interfaces. Right now the multi hosted boxes don't; work very well because OpenH323 mechanism, but we will fix that if someone ; server: bool: Enable running a gatekeeper on the main endpoint
;server = false
; You must define the binding interfaces. Right now the multi hosted boxes don't
; work very well because OpenH323 mechanism, but we will fix that if someone
; have any problem. ; have any problem.
interface1=10.0.0.1 interface1=10.0.0.1
; port: int: Port on which the gatekeeper listens for connections
;port = 1719
; name: string: Identifier of the gatekeeper
;name = YateGatekeeper
; ttl: int: Registrations time to live in seconds, 0 to disable
;ttl = 600
[incoming] [incoming]
; This section sets defaults for the incoming H.323 calls ; This section sets defaults for the incoming H.323 calls

View File

@ -300,7 +300,7 @@ public:
virtual BOOL GetUsersPassword(const PString& alias,PString& password) const; virtual BOOL GetUsersPassword(const PString& alias,PString& password) const;
private: private:
YateH323EndPoint& endpoint; YateH323EndPoint& m_endpoint;
}; };
class YateH323AudioSource : public DataSource, public PIndirectChannel class YateH323AudioSource : public DataSource, public PIndirectChannel
@ -358,9 +358,11 @@ public:
virtual H323Connection* CreateConnection(unsigned callReference, void* userData, virtual H323Connection* CreateConnection(unsigned callReference, void* userData,
H323Transport* transport, H323SignalPDU* setupPDU); H323Transport* transport, H323SignalPDU* setupPDU);
bool Init(const NamedList* params = 0); bool Init(const NamedList* params = 0);
bool startGkClient(int mode, const char* name = ""); bool startGkClient(int mode, int retry = 0, const char* name = "");
void asyncGkClient(int mode, const PString& name); void stopGkClient();
void asyncGkClient(int mode, const PString& name, int retry);
protected: protected:
bool internalGkClient(int mode, const PString& name);
YateGatekeeperServer* m_gkServer; YateGatekeeperServer* m_gkServer;
YateGkRegThread* m_thread; YateGkRegThread* m_thread;
}; };
@ -475,14 +477,15 @@ class YateGkRegThread : public PThread
{ {
PCLASSINFO(YateGkRegThread, PThread); PCLASSINFO(YateGkRegThread, PThread);
public: public:
YateGkRegThread(YateH323EndPoint* endpoint, int mode, const char* name = "") YateGkRegThread(YateH323EndPoint* endpoint, int mode, int retry = 0, const char* name = "")
: PThread(10000), m_ep(endpoint), m_mode(mode), m_name(name) : PThread(10000), m_ep(endpoint), m_mode(mode), m_retry(retry), m_name(name)
{ } { }
void Main() void Main()
{ m_ep->asyncGkClient(m_mode,m_name); } { m_ep->asyncGkClient(m_mode,m_name,m_retry); }
protected: protected:
YateH323EndPoint* m_ep; YateH323EndPoint* m_ep;
int m_mode; int m_mode;
int m_retry;
PString m_name; PString m_name;
}; };
@ -630,7 +633,7 @@ bool FakeH323CapabilityRegistration::IsRegistered(const PString& name)
YateGatekeeperServer::YateGatekeeperServer(YateH323EndPoint& ep) YateGatekeeperServer::YateGatekeeperServer(YateH323EndPoint& ep)
: H323GatekeeperServer(ep), endpoint(ep) : H323GatekeeperServer(ep), m_endpoint(ep)
{ {
Debug(&hplugin,DebugAll,"YateGatekeeperServer::YateGatekeeperServer() [%p]",this); Debug(&hplugin,DebugAll,"YateGatekeeperServer::YateGatekeeperServer() [%p]",this);
} }
@ -642,9 +645,18 @@ BOOL YateGatekeeperServer::Init()
const char* addr = 0; const char* addr = 0;
int i; int i;
for (i=1; (addr=s_cfg.getValue("gk",("interface"+String(i)).c_str())); i++){ for (i=1; (addr=s_cfg.getValue("gk",("interface"+String(i)).c_str())); i++){
if (!AddListener(new H323GatekeeperListener(endpoint, *this,s_cfg.getValue("gk","name","YateGatekeeper"),new H323TransportUDP(endpoint,PIPSocket::Address(addr),s_cfg.getIntValue("gk","port",1719),0)))) if (!AddListener(new H323GatekeeperListener(m_endpoint, *this,s_cfg.getValue("gk","name","YateGatekeeper"),new H323TransportUDP(m_endpoint,PIPSocket::Address(addr),s_cfg.getIntValue("gk","port",1719),0))))
Debug(DebugGoOn,"Can't start the Gk listener for address: %s",addr); Debug(DebugGoOn,"Can't start the Gk listener for address: %s",addr);
} }
i = s_cfg.getIntValue("gk","ttl",600);
if (i > 0) {
// adjust time to live between 1 minute and 1 day
if (i < 60)
i = 60;
if (i > 86400)
i = 86400;
SetTimeToLive(i);
}
return TRUE; return TRUE;
} }
@ -666,6 +678,7 @@ YateH323EndPoint::~YateH323EndPoint()
ClearAllCalls(H323Connection::EndedByTemporaryFailure, true); ClearAllCalls(H323Connection::EndedByTemporaryFailure, true);
if (m_gkServer) if (m_gkServer)
delete m_gkServer; delete m_gkServer;
stopGkClient();
if (m_thread) if (m_thread)
Debug(DebugFail,"Destroying YateH323EndPoint '%s' still having a YateGkRegThread %p [%p]", Debug(DebugFail,"Destroying YateH323EndPoint '%s' still having a YateGkRegThread %p [%p]",
safe(),m_thread,this); safe(),m_thread,this);
@ -760,7 +773,19 @@ bool YateH323EndPoint::Init(const NamedList* params)
ali = params->getValue("alias",ali); ali = params->getValue("alias",ali);
} }
SetLocalUserName(ali); SetLocalUserName(ali);
if (params && params->getBoolValue("gkclient")){ if (params && params->getBoolValue("gkclient")) {
int ttl = params->getIntValue("gkttl",300);
if (ttl > 0) {
// adjust time to live between 1 minute and 1 day
if (ttl < 60)
ttl = 60;
if (ttl > 86400)
ttl = 86400;
registrationTimeToLive.SetInterval(0,ttl);
}
int retry = params->getIntValue("gkretry",60);
if ((retry > 0) && (retry < 10))
retry = 10;
const char *p = params->getValue("password"); const char *p = params->getValue("password");
if (p) { if (p) {
SetGatekeeperPassword(p); SetGatekeeperPassword(p);
@ -769,11 +794,11 @@ bool YateH323EndPoint::Init(const NamedList* params)
const char* d = params->getValue("gkip"); const char* d = params->getValue("gkip");
const char* a = params->getValue("gkname"); const char* a = params->getValue("gkname");
if (d) if (d)
startGkClient(ByAddr,d); startGkClient(ByAddr,retry,d);
else if (a) else if (a)
startGkClient(ByName,a); startGkClient(ByName,retry,a);
else else
startGkClient(Discover); startGkClient(Discover,retry);
} }
} }
@ -787,7 +812,7 @@ bool YateH323EndPoint::Init(const NamedList* params)
} }
// Start a new PThread that performs GK discovery // Start a new PThread that performs GK discovery
bool YateH323EndPoint::startGkClient(int mode, const char* name) bool YateH323EndPoint::startGkClient(int mode, int retry, const char* name)
{ {
int retries = 10; int retries = 10;
hplugin.lock(); hplugin.lock();
@ -800,22 +825,42 @@ bool YateH323EndPoint::startGkClient(int mode, const char* name)
Thread::msleep(25); Thread::msleep(25);
hplugin.lock(); hplugin.lock();
} }
m_thread = new YateGkRegThread(this,mode,name); m_thread = new YateGkRegThread(this,mode,retry,name);
hplugin.unlock(); hplugin.unlock();
m_thread->SetAutoDelete(); m_thread->SetAutoDelete();
m_thread->Resume(); m_thread->Resume();
return true; return true;
} }
void YateH323EndPoint::asyncGkClient(int mode, const PString& name) void YateH323EndPoint::stopGkClient()
{
Lock lock(hplugin);
if (m_thread) {
Debug(&hplugin,DebugWarn,"Forcibly terminating old Gk client thread in '%s'",safe());
m_thread->Terminate();
m_thread = 0;
lock.drop();
RemoveGatekeeper();
}
}
void YateH323EndPoint::asyncGkClient(int mode, const PString& name, int retry)
{
while (!internalGkClient(mode,name) && (retry > 0))
Thread::sleep(retry);
hplugin.lock();
m_thread = 0;
hplugin.unlock();
}
bool YateH323EndPoint::internalGkClient(int mode, const PString& name)
{ {
switch (mode) { switch (mode) {
case ByAddr: case ByAddr:
if (SetGatekeeper(name,new H323TransportUDP(*this))) { if (SetGatekeeper(name,new H323TransportUDP(*this))) {
Debug(&hplugin,DebugInfo,"Connected '%s' to GK addr '%s'", Debug(&hplugin,DebugInfo,"Connected '%s' to GK addr '%s'",
safe(),(const char*)name); safe(),(const char*)name);
m_thread = 0; return true;
return;
} }
Debug(&hplugin,DebugWarn,"Failed to connect '%s' to GK addr '%s'", Debug(&hplugin,DebugWarn,"Failed to connect '%s' to GK addr '%s'",
safe(),(const char*)name); safe(),(const char*)name);
@ -824,8 +869,7 @@ void YateH323EndPoint::asyncGkClient(int mode, const PString& name)
if (LocateGatekeeper(name)) { if (LocateGatekeeper(name)) {
Debug(&hplugin,DebugInfo,"Connected '%s' to GK name '%s'", Debug(&hplugin,DebugInfo,"Connected '%s' to GK name '%s'",
safe(),(const char*)name); safe(),(const char*)name);
m_thread = 0; return true;
return;
} }
Debug(&hplugin,DebugWarn,"Failed to connect '%s' to GK name '%s'", Debug(&hplugin,DebugWarn,"Failed to connect '%s' to GK name '%s'",
safe(),(const char*)name); safe(),(const char*)name);
@ -833,18 +877,16 @@ void YateH323EndPoint::asyncGkClient(int mode, const PString& name)
case Discover: case Discover:
if (DiscoverGatekeeper(new H323TransportUDP(*this))) { if (DiscoverGatekeeper(new H323TransportUDP(*this))) {
Debug(&hplugin,DebugInfo,"Connected '%s' to discovered GK",safe()); Debug(&hplugin,DebugInfo,"Connected '%s' to discovered GK",safe());
m_thread = 0; return true;
return;
} }
Debug(&hplugin,DebugWarn,"Failed to discover a GK in '%s'",safe()); Debug(&hplugin,DebugWarn,"Failed to discover a GK in '%s'",safe());
break; break;
case Unregister: case Unregister:
RemoveGatekeeper(); RemoveGatekeeper();
m_thread = 0; Debug(&hplugin,DebugInfo,"Removed the GK in '%s'",safe());
return; return true;
} }
RemoveListener(0); return false;
m_thread = 0;
} }
YateH323Connection::YateH323Connection(YateH323EndPoint& endpoint, YateH323Connection::YateH323Connection(YateH323EndPoint& endpoint,
@ -1607,8 +1649,10 @@ BOOL YateGatekeeperServer::TranslateAliasAddressToSignalAddress(const H225_Alias
* proxied), or if has to be send to another gatekeeper we find out * proxied), or if has to be send to another gatekeeper we find out
* from the driver parameter * from the driver parameter
*/ */
if ((m.getParam("driver")) && (*(m.getParam("driver")) == "h323")) if ((m.getParam("driver")) && (*(m.getParam("driver")) == "h323")) {
s >> "/";
address = s.c_str(); address = s.c_str();
}
else { else {
s.clear(); s.clear();
s << "ip$" << s_cfg.getValue("gk","interface1") << ":" << s_cfg.getIntValue("ep","port",1720); s << "ip$" << s_cfg.getValue("gk","interface1") << ":" << s_cfg.getIntValue("ep","port",1720);