1394 lines
42 KiB
C
1394 lines
42 KiB
C
/*++
|
||
|
||
Copyright (c) 1990 Microsoft Corporation
|
||
|
||
Module Name:
|
||
rplpush.c
|
||
|
||
Abstract:
|
||
This module contains functions of the PUSH handler component
|
||
of the Replicator.
|
||
|
||
These functions handle the pull requests from a Pull Partner
|
||
|
||
|
||
Functions:
|
||
RplPushInit
|
||
ExecuteWrkItm
|
||
HandleAddVersMapReq
|
||
HandleSndEntriesReq
|
||
HandleUpdNtf
|
||
HandleUpdVersNoReq
|
||
|
||
Portability:
|
||
|
||
This module is portable
|
||
|
||
Author:
|
||
|
||
Pradeep Bahl (PradeepB) Jan-1993
|
||
|
||
Revision History:
|
||
|
||
Modification date Person Description of modification
|
||
----------------- ------- ----------------------------
|
||
--*/
|
||
|
||
/*
|
||
* Includes
|
||
*/
|
||
#include "wins.h"
|
||
#include "nmsnmh.h"
|
||
#include "nms.h"
|
||
#include "rpl.h"
|
||
#include "rplmsgf.h"
|
||
#include "rplpush.h"
|
||
#include "rplpull.h"
|
||
#include "winsevt.h"
|
||
#include "winsque.h"
|
||
#include "nmsdb.h"
|
||
#include "winsmsc.h"
|
||
#include "winscnf.h"
|
||
#include "comm.h"
|
||
|
||
|
||
/*
|
||
* Local Macro Declarations
|
||
*/
|
||
|
||
//
|
||
// The amount of time the push thread will wait after its last activity
|
||
// before exiting. This is kept to be 5 mts for now.
|
||
//
|
||
// It is a good idea to keep it less than the Min. Replication time
|
||
// interval
|
||
//
|
||
#define WAIT_TIME_BEFORE_EXITING (300000)
|
||
|
||
/*
|
||
* Local Typedef Declarations
|
||
*/
|
||
|
||
|
||
/*
|
||
* Global Variable Definitions
|
||
*/
|
||
|
||
HANDLE RplPushCnfEvtHdl;
|
||
|
||
BOOL fRplPushThdExists = FALSE;
|
||
|
||
/*
|
||
* Local Variable Definitions
|
||
*/
|
||
|
||
|
||
|
||
/*
|
||
* Local Function Prototype Declarations
|
||
*/
|
||
STATIC
|
||
STATUS
|
||
HandleAddVersMapReq(
|
||
PQUE_RPL_REQ_WRK_ITM_T pWrkItm
|
||
);
|
||
STATIC
|
||
STATUS
|
||
HandleSndEntriesReq(
|
||
PQUE_RPL_REQ_WRK_ITM_T pWrkItm
|
||
);
|
||
|
||
|
||
STATIC
|
||
VOID
|
||
HandleUpdNtf(
|
||
#if PRSCONN
|
||
BOOL fPrsConn,
|
||
#endif
|
||
PQUE_RPL_REQ_WRK_ITM_T pWrkItm
|
||
);
|
||
|
||
STATIC
|
||
VOID
|
||
HandleUpdVersNoReq(
|
||
PQUE_RPL_REQ_WRK_ITM_T pWrkItm
|
||
);
|
||
STATIC
|
||
VOID
|
||
ExecuteWrkItm(
|
||
PQUE_RPL_REQ_WRK_ITM_T pWrkItm
|
||
);
|
||
|
||
|
||
/* prototypes for functions local to this module go here */
|
||
|
||
STATUS
|
||
RplPushInit(
|
||
LPVOID pParam
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This function is the start function of the Push Thread.
|
||
The function blocks on an auto-reset event variable until signalled
|
||
|
||
When signalled it
|
||
dequeues a work item from from its work queue and executes it
|
||
|
||
Arguments:
|
||
pParam
|
||
|
||
Externals Used:
|
||
None
|
||
|
||
|
||
Return Value:
|
||
|
||
Success status codes -- WINS_SUCCESS
|
||
Error status codes -- WINS_FAILURE
|
||
|
||
Error Handling:
|
||
|
||
Called by:
|
||
ERplInit
|
||
|
||
Side Effects:
|
||
|
||
Comments:
|
||
None
|
||
--*/
|
||
{
|
||
HANDLE ThdEvtArr[2];
|
||
PQUE_RPL_REQ_WRK_ITM_T pWrkItm;
|
||
DWORD ArrInd;
|
||
DWORD RetVal;
|
||
BOOL fSignaled;
|
||
|
||
|
||
UNREFERENCED_PARAMETER(pParam);
|
||
try {
|
||
//
|
||
// Initialize the thd
|
||
//
|
||
NmsDbThdInit(WINS_E_RPLPUSH);
|
||
DBGMYNAME("Replicator Push Thread\n");
|
||
|
||
//
|
||
// We do this at each thread creation to save on STATIC storage. This
|
||
// way when the thread is not there we don't consume resources.
|
||
//
|
||
ThdEvtArr[0] = NmsTermEvt;
|
||
ThdEvtArr[1] = QueRplPushQueHd.EvtHdl;
|
||
|
||
while(TRUE)
|
||
{
|
||
try {
|
||
/*
|
||
* Block until signaled or until timer expiry
|
||
*/
|
||
WinsMscWaitTimedUntilSignaled(
|
||
ThdEvtArr,
|
||
2,
|
||
&ArrInd,
|
||
WAIT_TIME_BEFORE_EXITING,
|
||
&fSignaled
|
||
);
|
||
|
||
//
|
||
// If the wait was interrupted due to a termination signal or
|
||
// if the wait timed out, exit the thread.
|
||
//
|
||
if (!fSignaled || (ArrInd == 0))
|
||
{
|
||
//
|
||
// if the thread has timed out, we need to exit it. Before
|
||
// we do that, we check whether some thread sneaked in
|
||
// a message after the timeout
|
||
//
|
||
if (!fSignaled)
|
||
{
|
||
PQUE_HD_T pQueHd = pWinsQueQueHd[QUE_E_RPLPUSH];
|
||
|
||
//
|
||
// QueGetWrkItm also enters the Push thread's critical
|
||
// section. I don't want to write a separate function
|
||
// or overload the QueGetWrkItem function to avoid
|
||
// the double entry into the critical section.
|
||
//
|
||
EnterCriticalSection(&pQueHd->CrtSec);
|
||
RetVal = QueGetWrkItm(
|
||
QUE_E_RPLPUSH,
|
||
(LPVOID)&pWrkItm
|
||
);
|
||
//
|
||
// if we got a request execute it.
|
||
//
|
||
if (RetVal != WINS_NO_REQ)
|
||
{
|
||
LeaveCriticalSection(&pQueHd->CrtSec);
|
||
NmsDbOpenTables(WINS_E_RPLPUSH);
|
||
ExecuteWrkItm(pWrkItm);
|
||
NmsDbCloseTables();
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// set the flag to FALSE so that if a message
|
||
// comes for this Push thread, it is created.
|
||
//
|
||
fRplPushThdExists = FALSE;
|
||
WinsThdPool.ThdCount--;
|
||
|
||
WinsThdPool.RplThds[WINSTHD_RPL_PUSH_INDEX].
|
||
fTaken = FALSE;
|
||
|
||
//
|
||
// Be sure to close the handle, otherwise
|
||
// the thread object will stay.
|
||
//
|
||
CloseHandle(
|
||
WinsThdPool.RplThds[WINSTHD_RPL_PUSH_INDEX].
|
||
ThdHdl
|
||
);
|
||
LeaveCriticalSection(&pQueHd->CrtSec);
|
||
WinsMscTermThd(WINS_SUCCESS,
|
||
WINS_DB_SESSION_EXISTS);
|
||
}
|
||
}
|
||
else //signaled for termination by the main thread
|
||
{
|
||
WinsMscTermThd(WINS_SUCCESS,
|
||
WINS_DB_SESSION_EXISTS);
|
||
}
|
||
|
||
}
|
||
|
||
|
||
/*
|
||
*loop forever until all work items have been handled
|
||
*/
|
||
while(TRUE)
|
||
{
|
||
/*
|
||
* dequeue the request from the queue
|
||
*/
|
||
RetVal = QueGetWrkItm(
|
||
QUE_E_RPLPUSH,
|
||
(LPVOID)&pWrkItm
|
||
);
|
||
if (RetVal == WINS_NO_REQ)
|
||
{
|
||
break;
|
||
}
|
||
|
||
|
||
NmsDbOpenTables(WINS_E_RPLPUSH);
|
||
ExecuteWrkItm(pWrkItm);
|
||
NmsDbCloseTables();
|
||
|
||
//
|
||
// Check for termination here since WINS could be under
|
||
// stress with a large number of messages in the queue.
|
||
// We don't want to delay the stop.
|
||
//
|
||
WinsMscChkTermEvt(
|
||
#ifdef WINSDBG
|
||
WINS_E_RPLPUSH,
|
||
#endif
|
||
FALSE
|
||
);
|
||
}
|
||
} // end of try
|
||
except(EXCEPTION_EXECUTE_HANDLER) {
|
||
DBGPRINTEXC("Replicator Push thread");
|
||
WINSEVT_LOG_M(GetExceptionCode(), WINS_EVT_RPLPUSH_EXC);
|
||
}
|
||
|
||
} // end of while
|
||
} // end of try
|
||
|
||
except (EXCEPTION_EXECUTE_HANDLER) {
|
||
|
||
DBGPRINTEXC("Replicator Push thread");
|
||
WINSEVT_LOG_M(GetExceptionCode(), WINS_EVT_RPLPUSH_ABNORMAL_SHUTDOWN);
|
||
|
||
//
|
||
// If NmsDbThdInit comes back with an exception, it is possible
|
||
// that the session has not yet been started. Passing
|
||
// WINS_DB_SESSION_EXISTS however is ok
|
||
//
|
||
WinsMscTermThd(WINS_FAILURE, WINS_DB_SESSION_EXISTS);
|
||
}
|
||
//
|
||
// We should never get here.
|
||
//
|
||
return(WINS_FAILURE);
|
||
}
|
||
|
||
|
||
VOID
|
||
ExecuteWrkItm(
|
||
PQUE_RPL_REQ_WRK_ITM_T pWrkItm
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
The function executes a work item. The work item can either be
|
||
a push notification request from within this WINS (from an NBT thread)
|
||
or a replication request (from a remote WINS)
|
||
|
||
Arguments:
|
||
pWrkItm - ptr to a work item
|
||
|
||
Externals Used:
|
||
None
|
||
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
Error Handling:
|
||
|
||
Called by:
|
||
RplPushInit
|
||
|
||
Side Effects:
|
||
|
||
Comments:
|
||
None
|
||
--*/
|
||
|
||
{
|
||
|
||
RPLMSGF_MSG_OPCODE_E PullReqType_e;
|
||
#if PRSCONN
|
||
BOOL fPrsConn = FALSE;
|
||
#endif
|
||
BOOL fPushNtf = FALSE;
|
||
|
||
//
|
||
// get the opcode
|
||
//
|
||
RplMsgfUfmPullPnrReq(
|
||
pWrkItm->pMsg,
|
||
pWrkItm->MsgLen,
|
||
&PullReqType_e
|
||
);
|
||
|
||
switch(PullReqType_e)
|
||
{
|
||
|
||
case(RPLMSGF_E_ADDVERSNO_MAP_REQ):
|
||
HandleAddVersMapReq(pWrkItm);
|
||
#ifdef WINSDBG
|
||
NmsCtrs.RplPushCtrs.NoAddVersReq++;
|
||
#endif
|
||
break;
|
||
|
||
case(RPLMSGF_E_SNDENTRIES_REQ):
|
||
HandleSndEntriesReq(pWrkItm);
|
||
#ifdef WINSDBG
|
||
NmsCtrs.RplPushCtrs.NoSndEntReq++;
|
||
#endif
|
||
break;
|
||
#if PRSCONN
|
||
case(RPLMSGF_E_UPDATE_NTF_PRS):
|
||
case(RPLMSGF_E_UPDATE_NTF_PROP_PRS):
|
||
fPrsConn = TRUE;
|
||
#endif
|
||
case(RPLMSGF_E_UPDATE_NTF):
|
||
case(RPLMSGF_E_UPDATE_NTF_PROP):
|
||
|
||
fPushNtf = TRUE;
|
||
#if PRSCONN
|
||
HandleUpdNtf(fPrsConn, pWrkItm);
|
||
#else
|
||
HandleUpdNtf(pWrkItm);
|
||
#endif
|
||
|
||
#ifdef WINSDBG
|
||
NmsCtrs.RplPushCtrs.NoUpdNtfReq++;
|
||
#endif
|
||
break;
|
||
|
||
case(RPLMSGF_E_UPDVERSNO_REQ):
|
||
#ifdef WINSDBG
|
||
NmsCtrs.RplPushCtrs.NoUpdVersReq++;
|
||
#endif
|
||
HandleUpdVersNoReq(pWrkItm);
|
||
break;
|
||
|
||
default:
|
||
#ifdef WINSDBG
|
||
NmsCtrs.RplPushCtrs.NoInvReq++;
|
||
#endif
|
||
DBGPRINT1(ERR, "RplPush: ExecuteWrkItm: Invalid Opcode (%d)\n",
|
||
PullReqType_e);
|
||
WINSEVT_LOG_M(WINS_FAILURE, WINS_EVT_SFT_ERR);
|
||
break;
|
||
}
|
||
|
||
//
|
||
// If the message is not an update notification,
|
||
// Free the message buffer. For an update
|
||
// notification, the message is handed to
|
||
// the PULL thread to handle. Therefore, we should not free it
|
||
// The work items needs to be freed always since we always allocate
|
||
// a new work item when queuing a request.
|
||
//
|
||
if ( !fPushNtf)
|
||
{
|
||
ECommFreeBuff(pWrkItm->pMsg - COMM_HEADER_SIZE);
|
||
|
||
}
|
||
|
||
//
|
||
// Deallocate the work item
|
||
//
|
||
QueDeallocWrkItm( RplWrkItmHeapHdl, pWrkItm );
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
STATUS
|
||
HandleAddVersMapReq(
|
||
PQUE_RPL_REQ_WRK_ITM_T pWrkItm
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This function handles a "send address - version # " request
|
||
|
||
Arguments:
|
||
pWrkItm - Work item that carries the request and associated info
|
||
|
||
Externals Used:
|
||
None
|
||
|
||
|
||
Return Value:
|
||
|
||
Success status codes --
|
||
Error status codes --
|
||
|
||
Error Handling:
|
||
|
||
Called by:
|
||
|
||
Side Effects:
|
||
|
||
Comments:
|
||
None
|
||
--*/
|
||
{
|
||
|
||
LPBYTE pRspBuff;
|
||
DWORD RspMsgLen;
|
||
PRPL_ADD_VERS_NO_T pPullAddNVersNo;
|
||
DWORD i = 0;
|
||
DWORD MaxNoOfOwners;
|
||
PRPL_CONFIG_REC_T pPnr;
|
||
COMM_ADD_T WinsAdd;
|
||
BOOL fRplPnr = FALSE;
|
||
BOOL fExc = FALSE;
|
||
struct in_addr InAddr;
|
||
PCOMM_ADD_T pWinsAdd;
|
||
PNMSDB_WINS_STATE_E pWinsState_e;
|
||
DWORD SizeOfBuff;
|
||
BOOL fRspBuffAlloc = FALSE;
|
||
#if SUPPORT612WINS > 0
|
||
BOOL fIsPnrBeta1Wins;
|
||
#endif
|
||
|
||
DBGENTER("HandleAddVersMapReq\n");
|
||
|
||
//
|
||
// We need to handle this request only if
|
||
// either the WINS that sent this message is one of our
|
||
// pull pnrs or if the fRplOnlyWCnfPnrs in the registry is FALSE
|
||
//
|
||
|
||
EnterCriticalSection(&WinsCnfCnfCrtSec);
|
||
try {
|
||
if (WinsCnf.fRplOnlyWCnfPnrs)
|
||
{
|
||
if ((pPnr = WinsCnf.PushInfo.pPushCnfRecs) != NULL)
|
||
{
|
||
COMM_INIT_ADD_FR_DLG_HDL_M(&WinsAdd, &pWrkItm->DlgHdl);
|
||
|
||
//
|
||
// Search for the Cnf record for the WINS we want to
|
||
// send the PUSH notification to/Replicate with.
|
||
//
|
||
for (
|
||
;
|
||
(pPnr->WinsAdd.Add.IPAdd != INADDR_NONE)
|
||
&&
|
||
!fRplPnr;
|
||
// no third expression
|
||
)
|
||
{
|
||
//
|
||
// Check if this is the one we want
|
||
//
|
||
if (pPnr->WinsAdd.Add.IPAdd == WinsAdd.Add.IPAdd)
|
||
{
|
||
//
|
||
// We are done. Set the fRplPnr flag to TRUE so that
|
||
// we break out of the loop.
|
||
//
|
||
// Note: Don't use break since that would cause
|
||
// a search for a 'finally' block
|
||
//
|
||
fRplPnr = TRUE;
|
||
continue; //so that we break out of the loop
|
||
|
||
}
|
||
|
||
//
|
||
// Get the next record that follows this one sequentially
|
||
//
|
||
pPnr = WinsCnfGetNextRplCnfRec(
|
||
pPnr,
|
||
RPL_E_IN_SEQ //seq. traversal
|
||
);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
fRplPnr = TRUE;
|
||
}
|
||
}
|
||
except(EXCEPTION_EXECUTE_HANDLER) {
|
||
DBGPRINTEXC("HandleAddVersMapReq");
|
||
WINSEVT_LOG_M(GetExceptionCode(), WINS_EVT_EXC_PULL_TRIG_PROC);
|
||
fExc = TRUE;
|
||
}
|
||
LeaveCriticalSection(&WinsCnfCnfCrtSec);
|
||
try {
|
||
|
||
if (fRplPnr)
|
||
{
|
||
|
||
VERS_NO_T MinOwnVersNo;
|
||
BOOL fOwnInited = FALSE;
|
||
DWORD TotNoOfOwners;
|
||
|
||
MaxNoOfOwners = 0;
|
||
WINS_ASSIGN_INT_TO_LI_M(MinOwnVersNo, 1);
|
||
|
||
|
||
DBGPRINT1(TMP, "HandleAddVersMap: WINS (%x) made an AddVersMap request\n", WinsAdd.Add.IPAdd);
|
||
EnterCriticalSection(&NmsDbOwnAddTblCrtSec);
|
||
TotNoOfOwners = NmsDbNoOfOwners;
|
||
LeaveCriticalSection(&NmsDbOwnAddTblCrtSec);
|
||
WinsMscAlloc(sizeof(RPL_ADD_VERS_NO_T) * TotNoOfOwners, &pPullAddNVersNo);
|
||
|
||
//
|
||
// If version counter value > 1, we will send it
|
||
//
|
||
EnterCriticalSection(&NmsNmhNamRegCrtSec);
|
||
if (LiGtr(NmsNmhMyMaxVersNo, MinOwnVersNo))
|
||
{
|
||
/*
|
||
* Get the max. version no for entries owned by self
|
||
*
|
||
* The reason we subtract 1 from NmsNmhMyMaxVersNo is because
|
||
* it contains the version number to be given to the next record
|
||
* to be registered/updated.
|
||
*/
|
||
NMSNMH_DEC_VERS_NO_M(
|
||
NmsNmhMyMaxVersNo,
|
||
pPullAddNVersNo->VersNo
|
||
);
|
||
pPullAddNVersNo->OwnerWinsAdd = NmsLocalAdd;
|
||
pPullAddNVersNo->StartVersNo = NmsDbStartVersNo;
|
||
|
||
MaxNoOfOwners++;
|
||
fOwnInited = TRUE;
|
||
}
|
||
LeaveCriticalSection(&NmsNmhNamRegCrtSec);
|
||
|
||
|
||
//
|
||
// BUG 26196
|
||
// Note: These critical sections are taken in the order given below
|
||
// by the RPC thread executing GetConfig
|
||
//
|
||
EnterCriticalSection(&NmsDbOwnAddTblCrtSec);
|
||
EnterCriticalSection(&RplVersNoStoreCrtSec);
|
||
|
||
try {
|
||
for (i = 1; i < TotNoOfOwners; i++)
|
||
{
|
||
//
|
||
// If the highest version number for an owner as identified
|
||
// by the RplPullOwnerVersNo table is zero, there is no
|
||
// need to send the mapping of this owner. The reason
|
||
// we may have a such an entry in our in-memory table is
|
||
// because 1)All records of the owner got deleted. Local
|
||
// WINS got terminated and reinvoked. On reinvocation, it
|
||
// did not find any records in the db.
|
||
// 2)Local WINS received a Pull range
|
||
// request for an owner that it did not know about.
|
||
// Since Pull Range request comes in as a
|
||
// "SndEntries" request, the Push thread has
|
||
// no way of distinguishing it from a normal
|
||
// 2 message pull request. For a 2 message
|
||
// request, "SndEntries" request will always
|
||
// have a subset of the WINS servers that
|
||
// have records in our db.
|
||
//
|
||
if (LiGtrZero((pRplPullOwnerVersNo+i)->VersNo) &&
|
||
(pNmsDbOwnAddTbl+i)->WinsState_e == NMSDB_E_WINS_ACTIVE)
|
||
{
|
||
PVERS_NO_T pStartVersNo;
|
||
(pPullAddNVersNo+MaxNoOfOwners)->VersNo = (pRplPullOwnerVersNo+i)->VersNo;
|
||
//
|
||
// Note: Since RplPullOwnerVersNo[i] is > 0, the
|
||
// State of the entry can not be deleted (see
|
||
// RplPullPullEntrie)
|
||
//
|
||
RPL_FIND_ADD_BY_OWNER_ID_M(i, pWinsAdd, pWinsState_e,
|
||
pStartVersNo);
|
||
(pPullAddNVersNo+MaxNoOfOwners)->OwnerWinsAdd = *pWinsAdd;
|
||
(pPullAddNVersNo+MaxNoOfOwners++)->StartVersNo = *pStartVersNo;
|
||
DBGPRINT3(RPLPUSH, "HandleAddVersMap:Owner Add (%x) - Vers. No (%d %d)\n", pWinsAdd->Add.IPAdd, (pRplPullOwnerVersNo+i)->VersNo.HighPart, (pRplPullOwnerVersNo+i)->VersNo.LowPart);
|
||
}
|
||
PERF("Speed it up by using pointer arithmetic")
|
||
}
|
||
}
|
||
except(EXCEPTION_EXECUTE_HANDLER) {
|
||
DBGPRINTEXC("HandleAddVersMapReq");
|
||
DBGPRINT1(EXC, "HandleAddVersMapReq: Exc. while checking vers. nos of owners\n", GetExceptionCode());
|
||
WINSEVT_LOG_M(GetExceptionCode(), WINS_EVT_EXC_PULL_TRIG_PROC);
|
||
}
|
||
|
||
//
|
||
// Let us initialize RplPullOwnerVersNo entry for the local WINS
|
||
//
|
||
// This is done so that if we later on pull from the remote WINS,
|
||
// we don't end up pulling our own records
|
||
//
|
||
|
||
if (fOwnInited)
|
||
{
|
||
pRplPullOwnerVersNo->VersNo = pPullAddNVersNo->VersNo;
|
||
pRplPullOwnerVersNo->StartVersNo = pPullAddNVersNo->StartVersNo;
|
||
DBGPRINT3(RPLPUSH, "HandleAddVersMap: Owner Add (%x) - Vers. No (%d %d)\n", NmsLocalAdd.Add.IPAdd, (pRplPullOwnerVersNo+i)->VersNo.HighPart, (pRplPullOwnerVersNo+i)->VersNo.LowPart);
|
||
}
|
||
|
||
LeaveCriticalSection(&RplVersNoStoreCrtSec);
|
||
LeaveCriticalSection(&NmsDbOwnAddTblCrtSec);
|
||
|
||
#if SUPPORT612WINS > 0
|
||
COMM_IS_PNR_BETA1_WINS_M(&pWrkItm->DlgHdl, fIsPnrBeta1Wins);
|
||
#endif
|
||
|
||
SizeOfBuff = RPLMSGF_ADDVERSMAP_RSP_SIZE_M(MaxNoOfOwners);
|
||
WinsMscAlloc(SizeOfBuff, &pRspBuff);
|
||
fRspBuffAlloc = TRUE;
|
||
/*
|
||
* format the response
|
||
*/
|
||
RplMsgfFrmAddVersMapRsp(
|
||
#if SUPPORT612WINS > 0
|
||
fIsPnrBeta1Wins,
|
||
#endif
|
||
RPLMSGF_E_ADDVERSNO_MAP_RSP,
|
||
pRspBuff + COMM_N_TCP_HDR_SZ,
|
||
SizeOfBuff - COMM_N_TCP_HDR_SZ,
|
||
pPullAddNVersNo,
|
||
MaxNoOfOwners,
|
||
0,
|
||
&RspMsgLen
|
||
);
|
||
|
||
//
|
||
// Free the memory we allocated earlier
|
||
//
|
||
WinsMscDealloc(pPullAddNVersNo);
|
||
|
||
/*
|
||
* Send the response. We don't check the return code. ECommSndRsp
|
||
* may have failed due to communication failure. There is nothing
|
||
* more to be done for either the success of failure case.
|
||
*/
|
||
(VOID)ECommSndRsp(
|
||
&pWrkItm->DlgHdl,
|
||
pRspBuff + COMM_N_TCP_HDR_SZ,
|
||
RspMsgLen
|
||
);
|
||
|
||
//
|
||
// We don't end the dialogue. It will get terminated when
|
||
// the initiator terminates it.
|
||
//
|
||
}
|
||
else
|
||
{
|
||
if (!fExc)
|
||
{
|
||
COMM_INIT_ADD_FR_DLG_HDL_M(&WinsAdd, &pWrkItm->DlgHdl);
|
||
DBGPRINT1(RPLPUSH, "HandleAddVersMapReq: Got a pull request message from a WINS to which we are not allowed to push replicas. Address of WINS is (%x)\n",
|
||
WinsAdd.Add.IPAdd
|
||
);
|
||
COMM_HOST_TO_NET_L_M(WinsAdd.Add.IPAdd,InAddr.s_addr);
|
||
|
||
WinsMscLogEvtStrs(COMM_NETFORM_TO_ASCII_M(&InAddr),
|
||
WINS_EVT_ADD_VERS_MAP_REQ_NOT_ACCEPTED,
|
||
TRUE);
|
||
|
||
}
|
||
|
||
//
|
||
// We need to end the dialogue. The work item and the message
|
||
// will get deallocated by the caller
|
||
//
|
||
|
||
//
|
||
// End the implicit dialogue
|
||
//
|
||
(VOID)ECommEndDlg(&pWrkItm->DlgHdl);
|
||
}
|
||
|
||
}
|
||
except(EXCEPTION_EXECUTE_HANDLER) {
|
||
DBGPRINTEXC("HandleAddVersMapReq");
|
||
WINSEVT_LOG_M(GetExceptionCode(), WINS_EVT_RPLPUSH_EXC);
|
||
}
|
||
if (fRspBuffAlloc)
|
||
{
|
||
WinsMscDealloc(pRspBuff);
|
||
}
|
||
DBGLEAVE("HandleAddVersMapReq\n")
|
||
return(WINS_SUCCESS);
|
||
}
|
||
|
||
|
||
STATUS
|
||
HandleSndEntriesReq(
|
||
PQUE_RPL_REQ_WRK_ITM_T pWrkItm
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This function handles the "send data entries req"
|
||
|
||
Arguments:
|
||
pWrkItm - Work item carrying info about the "Send Entries" request from
|
||
a remote WINS
|
||
|
||
Externals Used:
|
||
None
|
||
|
||
|
||
Return Value:
|
||
|
||
Success status codes -- WINS_SUCCESS
|
||
Error status codes -- WINS_FAILURE
|
||
|
||
Error Handling:
|
||
|
||
Called by:
|
||
|
||
RplPushInit()
|
||
|
||
Side Effects:
|
||
|
||
Comments:
|
||
None
|
||
--*/
|
||
{
|
||
|
||
COMM_ADD_T WinsAdd; /*address of WINS server whose records
|
||
*are being requested*/
|
||
VERS_NO_T MaxVers, MinVers; /*max. amd min. versions of
|
||
*records*/
|
||
FUTURES("use NMSDB_ROW_INFO_T structure - Maybe")
|
||
PRPL_REC_ENTRY_T pBuff;
|
||
LPBYTE pStartBuff = NULL;
|
||
DWORD RspBufLen;
|
||
DWORD NoOfRecs = 0;
|
||
DWORD i;
|
||
LPBYTE pNewPos;
|
||
LPBYTE pTxBuff;
|
||
LPBYTE pStartTxBuff;
|
||
STATUS RetStat;
|
||
PWINSTHD_TLS_T pTls;
|
||
BOOL fGetDataRecs = FALSE;
|
||
PRPL_CONFIG_REC_T pPnr;
|
||
BOOL fOnlyDynRecs = FALSE;
|
||
DWORD RplType = WINSCNF_RPL_DEFAULT_TYPE;
|
||
DWORD RplTypeFMsg;
|
||
BYTE Name[1]; //dummy to prevent RtlCopyMemory from
|
||
//barfing
|
||
COMM_ADD_T ReqWinsAdd;
|
||
#if SUPPORT612WINS > 0
|
||
BOOL fIsPnrBeta1Wins;
|
||
#endif
|
||
|
||
DBGENTER("HandleSndEntriesReq\n");
|
||
GET_TLS_M(pTls);
|
||
pTls->HeapHdl = NULL;
|
||
//#ifdef WINSDBG
|
||
try {
|
||
//#endif
|
||
//
|
||
// Check if this is one of our configured partners. If yes,
|
||
// pass the value of fOnlyDynRecs to NmsDbGetDataRecs.
|
||
//
|
||
// We allow access to even those WINSs that are not partners since
|
||
// we need to let them do revalidation of replicas (except for
|
||
// this replication activity, all other from non-configured partners
|
||
// is stopped at the first step - HandleAddVersMapReq).
|
||
//
|
||
if ((pPnr = RplGetConfigRec(RPL_E_PUSH, &pWrkItm->DlgHdl, NULL)) != NULL)
|
||
{
|
||
fOnlyDynRecs = pPnr->fOnlyDynRecs;
|
||
RplType = pPnr->RplType;
|
||
}
|
||
|
||
#if SUPPORT612WINS > 0
|
||
COMM_IS_PNR_BETA1_WINS_M(&pWrkItm->DlgHdl, fIsPnrBeta1Wins);
|
||
#endif
|
||
/*
|
||
* Unformat the request message
|
||
*/
|
||
RplMsgfUfmSndEntriesReq(
|
||
#if SUPPORT612WINS > 0
|
||
fIsPnrBeta1Wins,
|
||
#endif
|
||
pWrkItm->pMsg + 4, /*past the
|
||
*opcode */
|
||
&WinsAdd,
|
||
&MaxVers,
|
||
&MinVers,
|
||
&RplTypeFMsg
|
||
);
|
||
// ASSERTMSG("Min. Vers. No is >= Max. Vers. No", LiGeq(MaxVers, MinVers));
|
||
|
||
FUTURES("Check if the request is a PULL RANGE request. If it is, honor it")
|
||
FUTURES("only if the Requesting WINS is under the PUSH key or RplOnlyWCnfPnrs")
|
||
FUTURES("is set to 0")
|
||
|
||
COMM_INIT_ADD_FR_DLG_HDL_M(&ReqWinsAdd, &pWrkItm->DlgHdl);
|
||
|
||
#ifdef WINSDBG
|
||
DBGPRINT2(TMP, "HandleSndEntriesReq: WINS (%x) made a SndEntries request for Owner = (%x) \n", ReqWinsAdd.Add.IPAdd, WinsAdd.Add.IPAdd);
|
||
DBGPRINT4(TMP, "HandleSndEntriesReq: Min Vers No (%d %d); Max Vers No = (%d %d)\n", MinVers.HighPart, MinVers.LowPart, MaxVers.HighPart, MaxVers.LowPart);
|
||
#endif
|
||
if (RplType == WINSCNF_RPL_DEFAULT_TYPE)
|
||
{
|
||
DBGPRINT2(RPLPUSH, "HandleSndEntriesReq: Pnr (%x) is requesting replication of type (%x)\n", ReqWinsAdd.Add.IPAdd, RplTypeFMsg);
|
||
// WINSEVT_LOG_INFO_M(ReqWinsAdd.Add.IPAdd, WINS_EVT_PNR_PARTIAL_RPL_TYPE);
|
||
RplType = RplTypeFMsg;
|
||
}
|
||
|
||
/*
|
||
*
|
||
* Call database manager function to get the records. No need
|
||
* to check the return status here
|
||
*/
|
||
(VOID)NmsDbGetDataRecs(
|
||
WINS_E_RPLPUSH,
|
||
THREAD_PRIORITY_NORMAL, //not looked at
|
||
MinVers,
|
||
MaxVers,
|
||
0, //not of use here
|
||
LiEqlZero(MaxVers) ? TRUE : FALSE, //if max. vers.
|
||
//no. is zero,
|
||
//we want all
|
||
//recs.
|
||
FALSE, //not looked at in this call
|
||
NULL, //must be NULL since we are not
|
||
//doing scavenging of clutter
|
||
&WinsAdd,
|
||
fOnlyDynRecs,
|
||
RplType,
|
||
(LPVOID *)&pStartBuff,
|
||
&RspBufLen,
|
||
&NoOfRecs
|
||
);
|
||
fGetDataRecs = TRUE;
|
||
//
|
||
// Allocate a buffer for transmitting the records. Even if the
|
||
// above function failed, we still should have received a buffer
|
||
// from it (pStartBuff). Note: RspBufLen contains the size of memory
|
||
// required for a flattened stream of records.
|
||
//
|
||
pStartTxBuff = WinsMscHeapAlloc(pTls->HeapHdl, RspBufLen);
|
||
pTxBuff = pStartTxBuff + COMM_N_TCP_HDR_SZ;
|
||
|
||
pBuff = (PRPL_REC_ENTRY_T)pStartBuff;
|
||
|
||
DBGPRINT4(RPLPUSH, "Formatting 1st record for sending --name (%s)\nfGrp (%d)\nVersNo (%d %d)\n", pBuff->pName/*pBuff->Name*/,
|
||
pBuff->fGrp,
|
||
pBuff->VersNo.HighPart,
|
||
pBuff->VersNo.LowPart
|
||
);
|
||
|
||
/*
|
||
* format the response
|
||
*
|
||
* Note: It is quite possible that NmsDbGetDataRecs retrieved 0
|
||
* records. Even if it did, we are still assured of getting
|
||
* a buffer of the RPL_CONFIG_REC_SIZE size. Since at the
|
||
* time of allocation, memory is 'zero'ed by default, we
|
||
* won't run into any problems in the following function
|
||
* call. Check out this function to reassure yourself.
|
||
*
|
||
* Like mentioned in NmsDbGetDataRecs, the following call
|
||
* will serve to format a valid response to the remote WINS
|
||
*/
|
||
RplMsgfFrmSndEntriesRsp(
|
||
#if SUPPORT612WINS > 0
|
||
fIsPnrBeta1Wins,
|
||
#endif
|
||
pTxBuff,
|
||
NoOfRecs,
|
||
NOTE("expedient HACK - for now. Later on modify FrmSndEntriesRsp ")
|
||
NoOfRecs ? pBuff->pName : Name,
|
||
pBuff->NameLen,
|
||
pBuff->fGrp,
|
||
pBuff->NoOfAdds,
|
||
pBuff->NodeAdd,
|
||
pBuff->Flag,
|
||
pBuff->VersNo,
|
||
TRUE, /*First time*/
|
||
&pNewPos
|
||
);
|
||
|
||
|
||
PERF("Change RplFrmSndEntriesRsp so that it does the looping itself")
|
||
for (i = 1; i < NoOfRecs; i++)
|
||
{
|
||
|
||
pBuff = (PRPL_REC_ENTRY_T)((LPBYTE)pBuff + RPL_REC_ENTRY_SIZE);
|
||
|
||
// DBGPRINT4(RPLPUSH, "Formatting record for sending --name (%s)\nfGrp (%d)\nVersNo (%d %d)\n", pBuff->pName/*pBuff->Name*/, pBuff->fGrp, pBuff->VersNo.HighPart, pBuff->VersNo.LowPart);
|
||
|
||
/*
|
||
* Format the response
|
||
*/
|
||
RplMsgfFrmSndEntriesRsp(
|
||
#if SUPPORT612WINS > 0
|
||
fIsPnrBeta1Wins,
|
||
#endif
|
||
pNewPos,
|
||
NoOfRecs, //not used by func
|
||
pBuff->pName,
|
||
pBuff->NameLen,
|
||
pBuff->fGrp,
|
||
pBuff->NoOfAdds,
|
||
pBuff->NodeAdd,
|
||
pBuff->Flag,
|
||
pBuff->VersNo,
|
||
FALSE, /*Not First time*/
|
||
&pNewPos
|
||
);
|
||
|
||
|
||
}
|
||
|
||
RspBufLen = (ULONG) (pNewPos - pTxBuff);
|
||
|
||
/*
|
||
* Call ECommSndRsp to send the response.
|
||
*/
|
||
RetStat = ECommSndRsp(
|
||
&pWrkItm->DlgHdl,
|
||
pTxBuff,
|
||
RspBufLen
|
||
);
|
||
|
||
#ifdef WINSDBG
|
||
{
|
||
// COMM_IP_ADD_T IPAdd;
|
||
|
||
struct in_addr InAdd;
|
||
// COMM_GET_IPADD_M(&pWrkItm->DlgHdl, &IPAdd);
|
||
InAdd.s_addr = htonl(ReqWinsAdd.Add.IPAdd);
|
||
|
||
if (RetStat != WINS_SUCCESS)
|
||
{
|
||
DBGPRINT2(RPLPUSH, "HandleSndEntriesReq: ERROR: Could not send (%d) records to WINS with address = (%s)\n",
|
||
NoOfRecs,
|
||
inet_ntoa(InAdd)
|
||
);
|
||
}
|
||
else
|
||
{
|
||
DBGPRINT2(RPLPUSH, "HandleSndEntriesReq: Sent (%d) records to WINS with address = (%s)\n",
|
||
NoOfRecs,
|
||
inet_ntoa(InAdd)
|
||
);
|
||
}
|
||
}
|
||
#endif
|
||
|
||
//#ifdef WINSDBG
|
||
}
|
||
except(EXCEPTION_EXECUTE_HANDLER) {
|
||
DBGPRINTEXC("HandleSndEntriesReq");
|
||
WINSEVT_LOG_M(GetExceptionCode(), WINS_EVT_RPLPUSH_EXC);
|
||
} //end of exception handler
|
||
//#endif
|
||
if (fGetDataRecs)
|
||
{
|
||
//
|
||
// Free the buffer, allocated by NmsDbGetDataRecs and the Tx Buff
|
||
//
|
||
// The work item and the message it holds are freed by the caller
|
||
//
|
||
pBuff = (PRPL_REC_ENTRY_T)pStartBuff;
|
||
for (i=0; i<NoOfRecs; i++)
|
||
{
|
||
DWORD EntType;
|
||
if (pBuff->pName != NULL)
|
||
{
|
||
WinsMscHeapFree(pTls->HeapHdl, pBuff->pName);
|
||
}
|
||
EntType = NMSDB_ENTRY_TYPE_M(pBuff->Flag);
|
||
|
||
if (((EntType == NMSDB_SPEC_GRP_ENTRY) || (EntType == NMSDB_MULTIHOMED_ENTRY)) && (pBuff->pNodeAdd != NULL))
|
||
{
|
||
WinsMscHeapFree(pTls->HeapHdl, pBuff->pNodeAdd);
|
||
}
|
||
pBuff = (PRPL_REC_ENTRY_T)((LPBYTE)pBuff + RPL_REC_ENTRY_SIZE);
|
||
}
|
||
WinsMscHeapFree(pTls->HeapHdl, pStartBuff);
|
||
WinsMscHeapFree(pTls->HeapHdl, pStartTxBuff);
|
||
WinsMscHeapDestroy(pTls->HeapHdl);
|
||
}
|
||
DBGLEAVE("HandleSndEntriesReq\n");
|
||
return(WINS_SUCCESS);
|
||
}
|
||
|
||
|
||
VOID
|
||
HandleUpdNtf(
|
||
#if PRSCONN
|
||
BOOL fPrsConn,
|
||
#endif
|
||
PQUE_RPL_REQ_WRK_ITM_T pWrkItm
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
This function is called to handle an update notification message
|
||
received from a remote WINS
|
||
|
||
Arguments:
|
||
fPrsConn - Indicates whether the connection is persistent or not
|
||
pWrkItm - Work Item containing the message and other relevant info
|
||
|
||
Externals Used:
|
||
None
|
||
|
||
Return Value:
|
||
None
|
||
|
||
Error Handling:
|
||
|
||
Called by:
|
||
RplPushInit()
|
||
|
||
Side Effects:
|
||
|
||
Comments:
|
||
None
|
||
--*/
|
||
|
||
{
|
||
PRPL_CONFIG_REC_T pPnr;
|
||
COMM_ADD_T WinsAdd;
|
||
BOOL fRplPnr = FALSE;
|
||
BOOL fExc = FALSE;
|
||
struct in_addr InAddr;
|
||
DWORD RplType;
|
||
|
||
|
||
DBGENTER("HandleUpdNtf - PUSH thread\n");
|
||
|
||
//
|
||
// We need to forward this request to the PULL thread only if
|
||
// either the WINS that sent this notification is one of our
|
||
// push pnrs or if the fRplOnlyWCnfPnrs in the registry is FALSE
|
||
//
|
||
FUTURES("user RplGetConfigRec instead of the following code")
|
||
|
||
EnterCriticalSection(&WinsCnfCnfCrtSec);
|
||
try {
|
||
if (WinsCnf.fRplOnlyWCnfPnrs)
|
||
{
|
||
if ((pPnr = WinsCnf.PullInfo.pPullCnfRecs) != NULL)
|
||
{
|
||
COMM_INIT_ADD_FR_DLG_HDL_M(&WinsAdd, &pWrkItm->DlgHdl);
|
||
|
||
//
|
||
// Search for the Cnf record for the WINS we want to
|
||
// send the PUSH notification to/Replicate with.
|
||
//
|
||
for (
|
||
;
|
||
(pPnr->WinsAdd.Add.IPAdd != INADDR_NONE)
|
||
&&
|
||
!fRplPnr;
|
||
// no third expression
|
||
)
|
||
{
|
||
//
|
||
// Check if this is the one we want
|
||
//
|
||
if (pPnr->WinsAdd.Add.IPAdd == WinsAdd.Add.IPAdd)
|
||
{
|
||
//
|
||
// We are done. Set the fRplPnr flag to TRUE so that
|
||
// we break out of the loop.
|
||
//
|
||
// Note: Don't use break since that would cause
|
||
// a search for a 'finally' block
|
||
//
|
||
fRplPnr = TRUE;
|
||
RplType = pPnr->RplType;
|
||
continue; //so that we break out of the loop
|
||
|
||
}
|
||
|
||
//
|
||
// Get the next record that follows this one sequentially
|
||
//
|
||
pPnr = WinsCnfGetNextRplCnfRec(
|
||
pPnr,
|
||
RPL_E_IN_SEQ //seq. traversal
|
||
);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
fRplPnr = TRUE;
|
||
RplType = WinsCnf.PullInfo.RplType;
|
||
}
|
||
}
|
||
except(EXCEPTION_EXECUTE_HANDLER) {
|
||
DBGPRINTEXC("HandleUpdNtf");
|
||
WINSEVT_LOG_M(GetExceptionCode(), WINS_EVT_EXC_PUSH_TRIG_PROC);
|
||
fExc = TRUE;
|
||
}
|
||
LeaveCriticalSection(&WinsCnfCnfCrtSec);
|
||
#ifdef WINSDBG
|
||
try {
|
||
#endif
|
||
if (fRplPnr)
|
||
{
|
||
//
|
||
// Inform the TCP listener thread that it should stop
|
||
// monitoring the dialogue since we are handing it over to
|
||
// the PULL thread
|
||
//
|
||
#if PRSCONN
|
||
if (!fPrsConn)
|
||
#endif
|
||
{
|
||
if (!ECommProcessDlg(&pWrkItm->DlgHdl, COMM_E_NTF_STOP_MON))
|
||
{
|
||
|
||
//
|
||
// Free the buffer
|
||
//
|
||
ECommFreeBuff(pWrkItm->pMsg - COMM_HEADER_SIZE);
|
||
DBGPRINT0(ERR, "HandleUpdNtf - PUSH thread. No Upd Ntf could be sent. It could be because the link went down\n");
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
COMM_INIT_ADD_FR_DLG_HDL_M(&WinsAdd, &pWrkItm->DlgHdl);
|
||
COMM_HOST_TO_NET_L_M(WinsAdd.Add.IPAdd,InAddr.s_addr);
|
||
|
||
WinsMscLogEvtStrs(COMM_NETFORM_TO_ASCII_M(&InAddr),
|
||
WINS_EVT_UPD_NTF_ACCEPTED, TRUE);
|
||
}
|
||
}
|
||
|
||
//
|
||
// Forward the request to the Pull thread
|
||
//
|
||
ERplInsertQue(
|
||
WINS_E_RPLPUSH,
|
||
QUE_E_CMD_HDL_PUSH_NTF,
|
||
&pWrkItm->DlgHdl,
|
||
pWrkItm->pMsg, //msg containing the push ntf
|
||
pWrkItm->MsgLen, //msg length
|
||
ULongToPtr(RplType), //context to pass
|
||
0 //no magic no
|
||
);
|
||
|
||
//
|
||
// The Pull thread will now terminate the dlg
|
||
//
|
||
}
|
||
else //we need to reject this trigger
|
||
{
|
||
if (!fExc)
|
||
{
|
||
COMM_INIT_ADD_FR_DLG_HDL_M(&WinsAdd, &pWrkItm->DlgHdl);
|
||
DBGPRINT1(RPLPUSH, "HandleUpdNtf: Got a push trigger from a WINS with which we are not allowed to pull replicas. Address of WINS is (%d)\n",
|
||
WinsAdd.Add.IPAdd
|
||
);
|
||
|
||
COMM_HOST_TO_NET_L_M(WinsAdd.Add.IPAdd,InAddr.s_addr);
|
||
|
||
WinsMscLogEvtStrs(COMM_NETFORM_TO_ASCII_M(&InAddr),
|
||
WINS_EVT_UPD_NTF_NOT_ACCEPTED, TRUE);
|
||
}
|
||
|
||
//
|
||
// We need to first deallocate the message and then end the
|
||
// dialogue. The work item will get deallocated by the caller
|
||
//
|
||
|
||
//
|
||
// Free the buffer
|
||
//
|
||
ECommFreeBuff(pWrkItm->pMsg - COMM_HEADER_SIZE);
|
||
|
||
//
|
||
// End the implicit dialogue
|
||
//
|
||
(VOID)ECommEndDlg(&pWrkItm->DlgHdl);
|
||
}
|
||
|
||
#ifdef WINSDBG
|
||
}
|
||
except(EXCEPTION_EXECUTE_HANDLER) {
|
||
DBGPRINTEXC("HandleUpdNtf");
|
||
WINSEVT_LOG_M(GetExceptionCode(), WINS_EVT_RPLPUSH_EXC);
|
||
}
|
||
#endif
|
||
|
||
DBGLEAVE("HandleUpdNtf - PUSH thread\n");
|
||
return;
|
||
}
|
||
|
||
VOID
|
||
HandleUpdVersNoReq(
|
||
PQUE_RPL_REQ_WRK_ITM_T pWrkItm
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
This function is called to handle an update version number
|
||
request received from a remote WINS
|
||
|
||
This message is sent by a remote WINS as a result of a clash
|
||
during replication.
|
||
|
||
Arguments:
|
||
pWrkItm - work item
|
||
|
||
Externals Used:
|
||
None
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
Error Handling:
|
||
|
||
Called by:
|
||
RplPushInit()
|
||
|
||
Side Effects:
|
||
|
||
Comments:
|
||
None
|
||
--*/
|
||
|
||
{
|
||
BYTE Name[NMSDB_MAX_NAM_LEN];
|
||
DWORD NameLen;
|
||
BYTE Rcode;
|
||
DWORD RspBuffLen;
|
||
BYTE RspBuff[RPLMSGF_UPDVERSNO_RSP_SIZE];
|
||
COMM_ADD_T WinsAdd;
|
||
struct in_addr InAddr;
|
||
|
||
DBGENTER("HandleUpdVerdNoReq\n");
|
||
|
||
#ifdef WINSDBG
|
||
try {
|
||
#endif
|
||
//
|
||
// log an event
|
||
//
|
||
COMM_GET_IPADD_M(&pWrkItm->DlgHdl, &WinsAdd.Add.IPAdd);
|
||
COMM_HOST_TO_NET_L_M(WinsAdd.Add.IPAdd,InAddr.s_addr);
|
||
WinsMscLogEvtStrs(COMM_NETFORM_TO_ASCII_M(&InAddr), WINS_EVT_REM_WINS_INF, TRUE);
|
||
|
||
/*
|
||
* Unformat the request message
|
||
*/
|
||
RplMsgfUfmUpdVersNoReq(
|
||
pWrkItm->pMsg + 4, /*past the
|
||
*opcode */
|
||
Name,
|
||
&NameLen
|
||
);
|
||
|
||
//
|
||
// handle the request
|
||
//
|
||
NmsNmhUpdVersNo( Name, NameLen, &Rcode, &WinsAdd );
|
||
|
||
|
||
//
|
||
//Format the response
|
||
//
|
||
RplMsgfFrmUpdVersNoRsp(
|
||
RspBuff + COMM_N_TCP_HDR_SZ,
|
||
Rcode,
|
||
&RspBuffLen
|
||
);
|
||
|
||
//
|
||
// Send the response. No need to check the return code.
|
||
//
|
||
(VOID)ECommSndRsp(
|
||
&pWrkItm->DlgHdl,
|
||
RspBuff + COMM_N_TCP_HDR_SZ,
|
||
RspBuffLen
|
||
);
|
||
|
||
//
|
||
// No need to end the dialogue. The initiator of the dlg will end it.
|
||
//
|
||
#ifdef WINSDBG
|
||
}
|
||
except(EXCEPTION_EXECUTE_HANDLER) {
|
||
DBGPRINTEXC("HandleUpdVersNoReq");
|
||
WINSEVT_LOG_M(GetExceptionCode(), WINS_EVT_RPLPUSH_EXC);
|
||
}
|
||
#endif
|
||
|
||
DBGLEAVE("HandleUpdVerdNoReq\n");
|
||
return;
|
||
|
||
} // HandleUpdVersNoReq()
|
||
|
||
|
||
|