From 653e3e14a2075e96f6cfbc05b75c9b4ca0153473 Mon Sep 17 00:00:00 2001 From: paulc Date: Fri, 22 Oct 2010 10:38:15 +0000 Subject: [PATCH] Fixed the alternate route detection algorithm. Always recompute all views including itself as in alternate routing a notification may be sent back. git-svn-id: http://yate.null.ro/svn/yate/trunk@3750 acf43c95-373e-0410-b603-e72c3f656dc1 --- libs/ysig/router.cpp | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/libs/ysig/router.cpp b/libs/ysig/router.cpp index eab3b8cd..eb4a8753 100644 --- a/libs/ysig/router.cpp +++ b/libs/ysig/router.cpp @@ -1002,8 +1002,6 @@ void SS7Router::routeChanged(const SS7Route* route, SS7PointCode::Type type, continue; if (!((forced && onlyPC) || (*l3p)->operational())) continue; - if (!(*l3p)->getRoutePriority(type,remotePC)) - continue; for (ObjList* v = l3p->view(type).skipNull(); v; v = v->skipNext()) { SS7Route* r = static_cast(v->get()); if (r->packed() != route->packed()) @@ -1076,6 +1074,7 @@ SS7Route::State SS7Router::getRouteView(SS7PointCode::Type type, unsigned int pa unsigned int routePrio = route ? route->priority() : (unsigned int)-1; // combine all matching routes not on current network SS7Route::State best = SS7Route::Unknown; + bool thisIsCurrent = (routeState & (SS7Route::NotProhibited|SS7Route::Unknown)) != 0; for (ObjList* o = m_layer3.skipNull(); o; o = o->skipNext()) { SS7Layer3* l3 = *static_cast(o->get()); if (!l3 || (l3 == network)) @@ -1090,16 +1089,12 @@ SS7Route::State SS7Router::getRouteView(SS7PointCode::Type type, unsigned int pa DDebug(this,DebugAll,"Operational '%s' is load sharing with '%s'", l3->toString().c_str(),network->toString().c_str()); best = SS7Route::Prohibited; - break; - } - if ((r->priority() > routePrio) && (routeState & SS7Route::NotProhibited)) { - // alternate - current is not allowed to send through us - DDebug(this,DebugAll,"Operational '%s' is alternate to %s '%s'", - l3->toString().c_str(),SS7Route::stateName(routeState),network->toString().c_str()); - best = SS7Route::Prohibited; + thisIsCurrent = false; break; } state = r->state(); + if ((r->priority() < routePrio || SS7Route::Unknown == routeState) && (state & SS7Route::NotProhibited)) + thisIsCurrent = false; DDebug(this,DebugAll,"Operational '%s' contributed state %s", l3->toString().c_str(),SS7Route::stateName(state)); } @@ -1111,6 +1106,10 @@ SS7Route::State SS7Router::getRouteView(SS7PointCode::Type type, unsigned int pa if ((state & SS7Route::KnownState) > (best & SS7Route::KnownState)) best = state; } + if (thisIsCurrent && (routePrio != (unsigned int)-1)) { + DDebug(this,DebugAll,"Route is current in an alternative set"); + best = SS7Route::Prohibited; + } DDebug(this,DebugInfo,"Route view of %u from %u%s%s: %s", packedPC,remotePC,(network ? " on " : ""), (network ? network->toString().c_str() : ""),SS7Route::stateName(best)); @@ -1495,15 +1494,15 @@ void SS7Router::clearRoutes(SS7Layer3* network, bool ok) unsigned int adjacent = 0; for (; l; l = l->skipNext()) { SS7Route* r = static_cast(l->get()); - if (ok && (r->state() != SS7Route::Prohibited)) - continue; if (!r->priority()) adjacent = r->packed(); + if (ok && (r->state() != SS7Route::Prohibited)) + continue; // if an adjacent node is operational but not in service we may have a chance SS7Route::State state = (ok || !r->priority()) ? SS7Route::Unknown : SS7Route::Prohibited; - DDebug(DebugInfo,"Clearing route %u/%u of %s to %s", + DDebug(DebugInfo,"Clearing route %u/%u of %s by %u to %s", r->packed(),r->priority(),network->toString().c_str(), - SS7Route::stateName(state)); + adjacent,SS7Route::stateName(state)); setRouteSpecificState(type,r->packed(),adjacent,state,network); } }