windows-nt/Source/XPSP1/NT/net/rras/ipx/rip/periodbc.c
2020-09-26 16:20:57 +08:00

162 lines
3 KiB
C

/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
periodbc.c
Abstract:
Contains the work item handler periodic bcast
Author:
Stefan Solomon 07/20/1995
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
/*++
Function: IfPeriodicBcast
Descr: called to initiate or continue (complete) a bcast
if EnumHandle is NULL it is a start, else a continuation
Remark: called with the interface lock held
--*/
VOID
IfPeriodicBcast(PWORK_ITEM wip)
{
UCHAR ripsocket[2];
USHORT pktlen;
ULONG delay;
PICB icbp;
icbp = wip->icbp;
#define EnumHandle wip->WorkItemSpecific.WIS_EnumRoutes.RtmEnumerationHandle
if(icbp->IfStats.RipIfOperState != OPER_STATE_UP) {
if(EnumHandle) {
CloseEnumHandle(EnumHandle);
}
FreeWorkItem(wip);
return;
}
PUTUSHORT2SHORT(ripsocket, IPX_RIP_SOCKET);
// check if this is the start or the continuation of a periodic bcast
if(EnumHandle == NULL) {
// *** This is the start of a new broadcast ***
// create an RTM enumeration handle
if((EnumHandle = CreateBestRoutesEnumHandle()) == NULL) {
SS_ASSERT(FALSE);
FreeWorkItem(wip);
return;
}
}
else
{
// *** This is the continuation of a started broadcast ***
// check if this was the last packet in the response
GETSHORT2USHORT(&pktlen, wip->Packet + IPXH_LENGTH);
if(pktlen < FULL_PACKET) {
// we are done
goto ResetPeriodicBcast;
}
// check the time stamp to determine if an interpacket gap is needed
delay = (wip->TimeStamp + 55) - GetTickCount();
if(delay < MAXULONG/2) {
// have to wait this delay
IfRefStartWiTimer(wip, delay);
return;
}
}
// make the gen response packet
pktlen = MakeRipGenResponsePacket(wip,
bcastnode,
ripsocket);
if(pktlen == EMPTY_PACKET) {
// we are done
goto ResetPeriodicBcast;
}
// send the bcast and increment the ref counter
if(IfRefSendSubmit(wip) != NO_ERROR) {
// can't send on this interface now -> requeue in timer and retry
goto ResetPeriodicBcast;
}
return;
ResetPeriodicBcast:
// no more routes to advertise for this general response
CloseEnumHandle(EnumHandle);
EnumHandle = NULL;
// enqueue for the bcast time in the timer queue
IfRefStartWiTimer(wip, PERIODIC_UPDATE_INTERVAL_MILISECS(icbp));
}
/*++
Function: IfPeriodicSendGenRequest
Descr: called to send periodically a gen request on a wan line for
a remote or local workstation dial. This is mainly to remain
compatible with NT 3.51 rip router which requires a gen request
in order to send its internal node (if client) or routing table
if server.
Remark: called with the interface lock held
--*/
VOID
IfPeriodicGenRequest(PWORK_ITEM wip)
{
PICB icbp;
icbp = wip->icbp;
if(icbp->IfStats.RipIfOperState != OPER_STATE_UP) {
FreeWorkItem(wip);
return;
}
SendRipGenRequest(icbp);
// enqueue the periodic send bcast in the timer queue
IfRefStartWiTimer(wip, 60000);
}