Skip to content

Commit

Permalink
new feature GnuGkAssignedGatekeeper to push endpoints back to their i…
Browse files Browse the repository at this point in the history
…ntended home gatekeepers
  • Loading branch information
willamowius committed Jun 4, 2020
1 parent b9539f1 commit c2a96a9
Show file tree
Hide file tree
Showing 11 changed files with 304 additions and 27 deletions.
12 changes: 12 additions & 0 deletions Neighbor.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -1740,6 +1740,18 @@ bool NeighborList::IsTraversalServer(const PIPSocket::Address & addr) const
return find_if(m_neighbors.begin(), m_neighbors.end(), bind2nd(mem_fun(&Neighbor::IsTraversalServer), &addr)) != m_neighbors.end();
}

// is IP a neighbor and is it not disabled ?
bool NeighborList::IsAvailable(const PIPSocket::Address & ip)
{
// Attempt to find the neighbor in the list
List::iterator findNeighbor = find_if(m_neighbors.begin(), m_neighbors.end(), bind2nd(mem_fun(&Neighbor::IsFrom), &ip));
if (findNeighbor == m_neighbors.end())
{
return false;
}
return !(*findNeighbor)->IsDisabled();
}

PString NeighborList::GetNeighborIdBySigAdr(const H225_TransportAddress & sigAd)
{
PIPSocket::Address ipaddr;
Expand Down
3 changes: 3 additions & 0 deletions Neighbor.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,9 @@ class NeighborList {
bool IsTraversalClient(const PIPSocket::Address &) const;
bool IsTraversalServer(const PIPSocket::Address &) const;

// is IP a neighbor and is it not disabled ?
bool IsAvailable(const PIPSocket::Address & ip);

// return the neighbor's ID from the list by signal address
PString GetNeighborIdBySigAdr(const H225_TransportAddress & sigAd);
PString GetNeighborIdBySigAdr(const PIPSocket::Address & sigAd);
Expand Down
12 changes: 10 additions & 2 deletions RasSrv.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -2644,7 +2644,7 @@ bool RegistrationRequestPDU::Process()
PTRACE(3, "RAS\tRRQ rejected by unknown reason from " << rx_addr);
return BuildRRJ(H225_RegistrationRejectReason::e_undefinedReason);
}
ep->SetRasServerIP(m_msg->m_localAddr); // remember which of our IPs the endpoint has sent the RRQ to (need for H.460.18 SCI)
ep->SetRasServerIP(m_msg->m_localAddr); // remember which of our IPs the endpoint has sent the RRQ to (needed for H.460.18 SCI)

#ifdef HAS_H46017
if (usesH46017) {
Expand Down Expand Up @@ -2878,8 +2878,16 @@ bool RegistrationRequestPDU::Process()
#endif

// Alternate GKs
if (request.HasOptionalField(H225_RegistrationRequest::e_supportsAltGK))
if (request.HasOptionalField(H225_RegistrationRequest::e_supportsAltGK)) {
RasSrv->SetAlternateGK(rcf, m_msg->m_peerAddr);
#if HAS_DATABASE
// check if we have GnuGk-assigned home gatekeepers
// TODO: make sure this DB query only runs on new registrations
if (Toolkit::Instance()->GnuGkAssignedGKs().HasAssignedGk(ep, m_msg->m_peerAddr)) {
PTRACE(2, "RCF\tEndpoint is assigned to other gatekeeper - will try to re-home");
}
#endif // HAS_DATABASE
}

// Call credit display
if (ep->AddCallCreditServiceControl(rcf.m_serviceControl,
Expand Down
2 changes: 1 addition & 1 deletion RasSrv.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ class RasServer : public Singleton<RasServer>, public SocketsReader {
}

#ifdef h323v6
template<class RAS> bool HasAssignedGK(const PString & alias,const PIPSocket::Address & ip, RAS & ras)
template<class RAS> bool HasAssignedGK(const PString & alias, const PIPSocket::Address & ip, RAS & ras)
{
H225_ArrayOf_AlternateGK assignedGK;
assignedGK.SetSize(0);
Expand Down
42 changes: 39 additions & 3 deletions RasTbl.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,12 @@ EndpointRec::EndpointRec(
m_H46024a(false), m_H46024b(false), m_natproxy(GkConfig()->GetBoolean(proxysection, "ProxyForNAT", false)),
m_internal(false), m_remote(false), m_h46017disabled(false), m_h46018disabled(false), m_usesH460P(false), m_hasH460PData(false),
m_usesH46017(false), m_usesH46026(false), m_traversalType(None), m_bandwidth(0), m_maxBandwidth(-1), m_useTLS(false),
m_useIPSec(false), m_additiveRegistrant(false), m_addCallingPartyToSourceAddress(false), m_authenticators(NULL)
m_useIPSec(false), m_additiveRegistrant(false), m_addCallingPartyToSourceAddress(false), m_authenticators(NULL),
m_hasGnuGkAssignedGk(false)
{
static H225_EndpointType defaultTermType; // nouse
m_terminalType = &defaultTermType;
m_registrationTime = PTime();

switch (m_RasMsg.GetTag())
{
Expand Down Expand Up @@ -953,6 +955,13 @@ EndpointRec *EndpointRec::Unregister()
return this;
}

EndpointRec *EndpointRec::UnregisterWithAlternate(H225_ArrayOf_AlternateGK * setAlternate)
{
if (!IsPermanent())
SendURQ(H225_UnregRequestReason::e_maintenance, 0, setAlternate);
return this;
}

EndpointRec *EndpointRec::Expired()
{
SendURQ(H225_UnregRequestReason::e_ttlExpired, 0);
Expand Down Expand Up @@ -1016,7 +1025,7 @@ PString EndpointRec::PrintOn(bool verbose) const
return msg;
}

bool EndpointRec::SendURQ(H225_UnregRequestReason::Choices reason, int preemption)
bool EndpointRec::SendURQ(H225_UnregRequestReason::Choices reason, int preemption, H225_ArrayOf_AlternateGK * setAlternate)
{
if ((GetRasAddress().GetTag() != H225_TransportAddress::e_ipAddress)
&& (GetRasAddress().GetTag() != H225_TransportAddress::e_ip6Address)
Expand All @@ -1034,6 +1043,12 @@ bool EndpointRec::SendURQ(H225_UnregRequestReason::Choices reason, int preemptio
urq.m_endpointIdentifier = GetEndpointIdentifier();
urq.m_callSignalAddress.SetSize(1);
urq.m_callSignalAddress[0] = GetCallSignalAddress();
// alternate given as parameter
if (setAlternate) {
urq.IncludeOptionalField(H225_UnregistrationRequest::e_alternateGatekeeper);
urq.m_alternateGatekeeper = *setAlternate;
}
// when in maintenance mode, use that as alternate
if (Toolkit::Instance()->IsMaintenanceMode()) {
H225_ArrayOf_AlternateGK alternates = Toolkit::Instance()->GetMaintenanceAlternate();
if (alternates.GetSize() > 0) {
Expand Down Expand Up @@ -2373,11 +2388,32 @@ void RegistrationTable::UpdateTable()
void RegistrationTable::CheckEndpoints()
{
PTime now;
RasServer * RasSrv = RasServer::Instance();
time_t rehomingWait = GkConfig()->GetInteger("GnuGkAssignedGatekeepers::SQL", "RehomingWait", 300); // in sec, default 5 min
WriteLock lock(listLock);

iterator Iter = EndpointList.begin();
while (Iter != EndpointList.end()) {
EndpointRec *ep = *Iter;
// check GnuGk-Assigned gatekeeper
if (ep->HasGnuGkAssignedGk()) {
// check how long EP is registered here, don't try sending it away before n sec/min (switch!)
if (now - ep->GetRegistrationTime() > rehomingWait) {
callptr call = CallTable::Instance()->FindCallRec(endptr(ep));
if (!call) {
if (RasSrv->GetNeighbors()->IsAvailable(ep->GetGnuGkAssignedGk())) {
H225_ArrayOf_AlternateGK alternate;
alternate.SetSize(1);
alternate[0].m_rasAddress = SocketToH225TransportAddr(ep->GetGnuGkAssignedGk(), GK_DEF_UNICAST_RAS_PORT);
alternate[0].m_needToRegister = true;
alternate[0].m_priority = 1;
ep->UnregisterWithAlternate(&alternate);
}
}
}
}

// check expired registrations
if (!ep->IsUpdated(&now) && !ep->SendIRQ()) {
if (!Toolkit::AsBool(GkConfig()->GetString("Gatekeeper::Main", "TTLExpireDropCall", "1"))
&& CallTable::Instance()->FindCallRec(endptr(ep))) {
Expand All @@ -2388,7 +2424,7 @@ void RegistrationTable::CheckEndpoints()
}
SoftPBX::DisconnectEndpoint(endptr(ep));
ep->Expired();
RasServer::Instance()->LogAcctEvent(GkAcctLogger::AcctUnregister, endptr(ep));
RasSrv->LogAcctEvent(GkAcctLogger::AcctUnregister, endptr(ep));
RemovedList.push_back(ep);
Iter = EndpointList.erase(Iter);
--regSize;
Expand Down
21 changes: 18 additions & 3 deletions RasTbl.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ class EndpointRec
virtual EndpointRec *Unregisterpreempt(int type);
virtual EndpointRec *Reregister();
virtual EndpointRec *Unregister();
virtual EndpointRec *UnregisterWithAlternate(H225_ArrayOf_AlternateGK * setAlternate);
virtual EndpointRec *Expired();

virtual PString PrintOn(bool verbose) const;
Expand Down Expand Up @@ -242,6 +243,7 @@ class EndpointRec

int Priority() const { return m_registrationPriority; }
PTime GetUpdatedTime() const;
PTime GetRegistrationTime() const;

void SetUsesH460P(bool uses);
bool UsesH460P() const { return m_usesH460P; }
Expand Down Expand Up @@ -345,6 +347,10 @@ class EndpointRec
bool AddCallingPartyToSourceAddress() const { return m_addCallingPartyToSourceAddress; }
PString GetDisabledCodecs() const { return m_disabledcodecs; }

void SetGnuGkAssignedGk(const PIPSocket::Address & addr) { m_hasGnuGkAssignedGk = true; m_GnuGkAssignedGk = addr; }
bool HasGnuGkAssignedGk() const { return m_hasGnuGkAssignedGk; }
PIPSocket::Address GetGnuGkAssignedGk() const { return m_GnuGkAssignedGk; }

// smart pointer for EndpointRec
typedef SmartPtr<EndpointRec> Ptr;

Expand All @@ -355,7 +361,7 @@ class EndpointRec
void SetEndpointRec(H225_LocationConfirm &);
void SetEndpointRec(H225_UnregistrationRequest &); // used for temp objects

bool SendURQ(H225_UnregRequestReason::Choices, int preemption);
bool SendURQ(H225_UnregRequestReason::Choices, int preemption, H225_ArrayOf_AlternateGK * setAlternate = NULL);

private:
/// Load general endpoint settings from the config
Expand Down Expand Up @@ -390,7 +396,8 @@ class EndpointRec
int m_pollCount, m_usedCount;
mutable PMutex m_usedLock;

PTime m_updatedTime;
PTime m_updatedTime; // last update from EP
PTime m_registrationTime; // time when the EP registered
bool m_fromParent, m_nat;
PIPSocket::Address m_natip;
CallSignalSocket *m_natsocket;
Expand Down Expand Up @@ -443,6 +450,8 @@ class EndpointRec
PString m_disabledcodecs;
/// H.235 used to authenticate this endpoint
GkH235Authenticators * m_authenticators;
bool m_hasGnuGkAssignedGk;
PIPSocket::Address m_GnuGkAssignedGk;
};

typedef EndpointRec::Ptr endptr;
Expand All @@ -460,7 +469,7 @@ class GatewayRec : public EndpointRec {
virtual void Update(const H225_RasMessage & lightweightRRQ);
virtual bool IsGateway() const { return true; }

/// Overiden from EndpointRec
/// Overridden from EndpointRec
virtual bool LoadConfig();

/** Find if at least one of the given aliases matches any prefix
Expand Down Expand Up @@ -2078,6 +2087,12 @@ inline PTime EndpointRec::GetUpdatedTime() const
return m_updatedTime;
}

inline PTime EndpointRec::GetRegistrationTime() const
{
PWaitAndSignal lock(m_usedLock);
return m_registrationTime;
}

inline H225_RasMessage EndpointRec::GetCompleteRegistrationRequest() const
{
PWaitAndSignal lock(m_usedLock);
Expand Down
Loading

0 comments on commit c2a96a9

Please sign in to comment.