📄 rtable.c
字号:
// Save the expiration
prt->dwTimeout = dwExp;
// Now add the entry to the list
// Check the easy case - being first
if( !prtFirstExp || prtFirstExp->dwTimeout >= dwExp )
{
// What we point to next
prt->pNextExp = prtFirstExp;
// Before us...pointing to us
prtFirstExp = prt;
}
else
{
// Find an entry we expire AFTER
prtTmp = prtFirstExp;
while( prtTmp->pNextExp &&
prtTmp->pNextExp->dwTimeout < dwExp )
prtTmp = prtTmp->pNextExp;
// What we point to next
prt->pNextExp = prtTmp->pNextExp;
// Before us...pointing to us
prtTmp->pNextExp = prt;
}
}
}
//--------------------------------------------------------------------
// _RtExpListRemove - Remove route from expiration list
//
// Note: Normally, routes will be removed off the top of the list.
// However, if the route is prematurely removed, it may be anywhere
// in the list.
//--------------------------------------------------------------------
void _RtExpListRemove( RT *prt )
{
RT *prtTmp;
// Clear the expiration time
prt->dwTimeout = 0;
// Check to see if we're the head of the list
if( prt == prtFirstExp )
prtFirstExp = prt->pNextExp;
else
{
// Look for us
prtTmp = prtFirstExp;
while( prtTmp && prtTmp->pNextExp != prt )
prtTmp = prtTmp->pNextExp;
// Patch entry which points to us
if( prtTmp )
prtTmp->pNextExp = prt->pNextExp;
}
}
//--------------------------------------------------------------------
// RtWalkBegin - Get First Route in Tree
//
// (Refs returned route)
//--------------------------------------------------------------------
HANDLE RtWalkBegin()
{
HANDLE hNode;
HANDLE hRt = 0;
// Disable Timeouts
_RtNoTimer++;
// Get the first node
hNode = NodeWalk( 0 );
// Return the first route on the fist node
while( hNode && !hRt )
{
if( hRt = NodeGetRt( hNode ) )
RtRef( hRt );
else
hNode = NodeWalk( hNode );
}
return( hRt );
}
//--------------------------------------------------------------------
// RtWalkNext - Get Next Route in Tree
//
// (DeRefs supplied route)
// (Refs returned route)
//--------------------------------------------------------------------
HANDLE RtWalkNext( HANDLE hRt )
{
RT *prt = (RT *)hRt;
RT *prtRet = 0;
HANDLE hNode;
if( prt->Type != HTYPE_RT )
{
DbgPrintf(DBG_ERROR,"RtWalkGetNext: HTYPE %04x",prt->Type);
return(0);
}
// First walk down the Rt list
if( prtRet = prt->pNext )
RtRef( prtRet );
else
{
hNode = NodeWalk( prt->hNode );
while( hNode && !prtRet )
{
if( (prtRet = (RT*)NodeGetRt( hNode )) )
RtRef( prtRet );
else
hNode = NodeWalk( hNode );
}
}
RtDeRef( prt );
return( prtRet );
}
//--------------------------------------------------------------------
// RtWalkEnd - End Tree Walk
//
//--------------------------------------------------------------------
void RtWalkEnd( HANDLE hRt )
{
if( hRt )
{
if( ((RT*)hRt)->Type != HTYPE_RT )
DbgPrintf(DBG_ERROR,"RtWalkEnd: Bad HTYPE");
else
RtDeRef( hRt );
}
// Enable Timeouts
if( _RtNoTimer )
_RtNoTimer--;
}
void RtDiag()
{
RT *prt;
UINT32 dwTimeNow;
if( _RtNoTimer )
DbgPrintf(DBG_INFO,"RtDiag: Timeouts Disabled");
else
DbgPrintf(DBG_INFO,"RtDiag: Timeouts Enabled");
DbgPrintf(DBG_INFO,"RtDiag: Expiration Check:%lu Attempt:%lu Revive:%lu",
dwTestChecked,dwTestAttempt,dwTestRevived);
dwTimeNow = llTimerGetTime(0);
prt = prtFirstExp;
if( !prt )
DbgPrintf(DBG_INFO,"RtDiag: No routes in Timeout List!");
else if( (prt->dwTimeout+6l) <= dwTimeNow )
DbgPrintf(DBG_INFO,"RtDiag: Timeout Overdue");
else if( prt->dwTimeout <= dwTimeNow )
DbgPrintf(DBG_INFO,"RtDiag: Timeout Pending");
else
DbgPrintf(DBG_INFO,"RtDiag: Next Timeout in %lu Seconds",
prt->dwTimeout-dwTimeNow);
}
//---------------------------------------------------------------------
// RtFind - Find a route
//
// Flags:
// FLG_RTF_CLONE Create cloned entry if needed
// FLG_RTF_REPORT Report any new or unfound route
// FLG_RTF_HOST Find only non-PROXYPUB HOST routes
// FLG_RTF_PROXY Find only PROXY or PROXYPUB routes
// FLG_RTF_PROXYPUB Find only PROXY or PROXYPUB routes
//
// (Bumps reference count)
//---------------------------------------------------------------------
HANDLE RtFind( uint wCallFlags, IPN dwIP )
{
RT *prt,*prtClone;
int Search = 1;
HANDLE hNode = 0;
while( Search )
{
// The following is guaranteed to find a node
hNode = NodeFind( dwIP, hNode );
// Now we need to find the "best" route on this node.
// Note: Our search can be affected by the call flags
// Get the route
prt = (RT *)NodeGetRt( hNode );
// We'll set the following flag to TRUE if we pass over a match
Search = 0;
while( prt )
{
// Try this route
if( (dwIP & prt->dwIPMask) != (prt->dwIPAddr & prt->dwIPMask) )
goto RouteNotAccepted;
// Quit now if there are no matching conditions
if( !(wCallFlags & FLG_RTF_CONDITIONAL) )
break;
// If we discard the match due to search criteria, first
// mark if we can or can not continue. We don't continue
// if we are at the far left node.
if( prt->dwIPAddr & prt->dwIPMask )
Search = 1;
// Host only search
if( wCallFlags & FLG_RTF_HOST )
{
// If Cloning is not set, we must have an exact host match,
// otherwise; we will accept a route that can clone into a
// host route.
if( (prt->Flags & (FLG_RTE_HOST|FLG_RTE_PROXY|
FLG_RTE_PROXYPUB|FLG_RTE_GATEWAY)) != FLG_RTE_HOST )
{
// We will reject this route unless it is a viable clone
// route and the caller wants to clone.
if( !(wCallFlags & FLG_RTF_CLONE) )
goto RouteNotAccepted;
if( !(prt->Flags & FLG_RTE_CLONING) )
goto RouteNotAccepted;
}
break;
}
// Proxy only search
if( wCallFlags & FLG_RTF_PROXY )
{
if( !(prt->Flags & FLG_RTE_PROXY) )
goto RouteNotAccepted;
break;
}
// ProxyPub only search
if( wCallFlags & FLG_RTF_PROXYPUB )
{
if( !(prt->Flags & FLG_RTE_PROXYPUB) )
goto RouteNotAccepted;
break;
}
// This route is acceptable
break;
RouteNotAccepted:
// No match yet
prt = prt->pNext;
}
// Reference the matched route (if any)
if( prt )
{
RtRef( prt );
Search = 0;
}
}
// We no longer need the node
NodeDeRef( hNode );
// If we have a route, we may need to clone it
if( prt && (prt->Flags & FLG_RTE_CLONING) && (wCallFlags & FLG_RTF_CLONE) )
{
uint NewFlags;
// Yep, we have to clone ...
// Copy the flags
NewFlags = prt->Flags;
// Clear the flags that don't carry over
NewFlags &= ~(FLG_RTE_CLONING|FLG_RTE_STATIC|FLG_RTE_DYNAMIC);
// Make us a host
NewFlags |= FLG_RTE_HOST;
if( !(prtClone = RtCreate( wCallFlags, NewFlags, dwIP, 0xffffffff,
prt->hIF, prt->dwIPGate, 0 )) )
DbgPrintf(DBG_WARN,"RtFind: Clone creation failed!");
else
{
// Mark as "keep-alive" route
prtClone->Flags |= FLG_RTE_KEEPALIVE;
// Set Default Timeout for Clone Node
RtSetTimeout( prtClone, ROUTE_CLONE_TIMEOUT );
}
// DeRef the source node
RtDeRef( prt );
// We now use the clone node
prt = prtClone;
}
// If we have no match, this is a "miss"
if( !prt )
{
// Miss! Post a report if needed
if( wCallFlags & FLG_RTF_REPORT )
{
// Send Routing Report
RTCReport( MSG_RTC_MISS, dwIP, 0xffffffff );
}
}
// NOTE: prt contains one of three things:
// 1. NULL for a "miss"
// 2. The referenced original route found
// 3. The referenced clone route (original unreferenced above).
return( prt );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -