windows-nt/Source/XPSP1/NT/net/wins/server/inc/rpl.h
2020-09-26 16:20:57 +08:00

497 lines
16 KiB
C

#ifndef _RPL_
#define _RPL_
/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
Abstract:
Functions:
Portability:
This header is portable.
Author:
Pradeep Bahl (PradeepB) Jan-1993
Revision History:
Modification Date Person Description of Modification
------------------ ------- ---------------------------
--*/
/*
includes
*/
#include "wins.h"
#include "comm.h"
#include "nmsdb.h"
#include "winsque.h"
/*
defines
*/
/*
RPL_OPCODE_SIZE -- size of opcode in message sent between two replicators.
This define is used by rplmsgf
*/
#define RPL_OPCODE_SIZE 4 //sizeof the Opcode in an RPL message
/*
The maximum numbers of RQ WINS on a network.
*/
#define RPL_MAX_OWNERS_INITIALLY NMSDB_MAX_OWNERS_INITIALLY
/*
RPL_MAX_GRP_MEMBERS --
Maximum members allowed in a group
*/
#define RPL_MAX_GRP_MEMBERS 25
//
// We don't send more than 5000 records at a time. Note: This value is
// used to define MAX_BYTES_IN_MSG in comm.c
//
// By not having a very bug number we have a better chance for being serviced
// within our timeout period for a request. This is because of queuing that
// results when there are a lot of replication requests
//
//
#define RPL_MAX_LIMIT_FOR_RPL 5000
/*
This define is used by ReadPartnerInfo and by RplPull functions. The size
is made a multiple of 8. I could have used sizeof(LARGE_INTEGER) instead of
8 but I am not sure whether that will remain a multiple of 8 in the future.
The size is made a multiple of 8 to avoid alignment exceptions on MIPS (
check out ReadPartnerInfo in winscnf.c or GetReplicas in rplpull.c for
more details)
*/
#define RPL_CONFIG_REC_SIZE (sizeof(RPL_CONFIG_REC_T) + \
(8 - sizeof(RPL_CONFIG_REC_T)%8))
//
// check out GetDataRecs in nmsdb.c
//
#define RPL_REC_ENTRY_SIZE (sizeof(RPL_REC_ENTRY_T) + \
(8 - sizeof(RPL_REC_ENTRY_T)%8))
//
// check out GetDataRecs in nmsdb.c
//
#define RPL_REC_ENTRY2_SIZE (sizeof(RPL_REC_ENTRY2_T) + \
(8 - sizeof(RPL_REC_ENTRY2_T)%8))
//
// The following define is used to initialize the TimeInterval/UpdateCount
// field of a RPL_REC_ENTRY_T structure to indicate that it is invalid
//
#define RPL_INVALID_METRIC -1
//
// defines to indicate whether the trigger needs to be propagated to all WINS
// in the PUSH chain
//
#define RPL_PUSH_PROP TRUE //must remain TRUE since in
//NmsNmhNamRegInd, at one place
//we use fAddDiff value in place of
//this symbol. fAddDiff when TRUE
//indicates that the address has
//changed, thus initiating propagation
#define RPL_PUSH_NO_PROP FALSE
/*
macros
*/
//
// Macro called in an NBT thread after it increments the version number
// counter. This macro is supposed to be called from within the
// NmsNmhNamRegCrtSec.
//
#define RPL_PUSH_NTF_M(fAddDiff, pCtx, pNoPushWins1, pNoPushWins2) { \
if ((WinsCnf.PushInfo.NoPushRecsWValUpdCnt \
!= 0) || \
fAddDiff) \
{ \
ERplPushProc(fAddDiff, pCtx, pNoPushWins1, \
pNoPushWins2); \
} \
}
/*
FIND_ADD_BY_OWNER_ID_M - This macro is called by the PUSH thread
when sending data records to its Pull Partner. It calls this function
to determine the Address of the WINS owning the database record
The caller of this macro, if not executing in the PULL thread, must
synchronize using NmsDbOwnAddTblCrtSec (Only PULL thread updates
the NmsDbOwnAddTbl array during steady state).
I am not putting the critical section entry and exit inside this
macro for performance reasons (refer StoreGrpMems in nmsdb.c where
this macro may be called many times -once for each member of a
special group). Also refer RplMsgfFrmAddVersMapRsp() and
WinsRecordAction (in winsintf.c)
*/
#define RPL_FIND_ADD_BY_OWNER_ID_M(OwnerId, pWinsAdd, pWinsState_e, pStartVersNo) \
{ \
PNMSDB_ADD_STATE_T pWinsRec; \
if (OwnerId < NmsDbTotNoOfSlots) \
{ \
pWinsRec = pNmsDbOwnAddTbl+OwnerId; \
(pWinsAdd) = &(pWinsRec->WinsAdd); \
(pWinsState_e) = &pWinsRec->WinsState_e; \
(pStartVersNo) = &pWinsRec->StartVersNo; \
} \
else \
{ \
(pWinsAdd) = NULL; \
(pWinsState_e) = NULL; \
(pStartVersNo) = NULL; \
} \
}
//
// Names of event variables signaled when Pull and/or Push configuration
// changes
//
#define RPL_PULL_CNF_EVT_NM TEXT("RplPullCnfEvt")
#define RPL_PUSH_CNF_EVT_NM TEXT("RplPushCnfEvt")
/*
externs
*/
/*
Handle of heap used for allocating/deallocating work items for the RPL
queues
*/
extern HANDLE RplWrkItmHeapHdl;
#if 0
extern HANDLE RplRecHeapHdl;
#endif
/*
OwnerIdAddressTbl
This table stores the Addresses corresponding to different WINS servers.
In the local database, the local WINS's owner id is always 0. The owner ids
of other WINS servers are 1, 2, 3 .... The owner ids form a sequential list,
without any gap. This is because, the first time the database is created
at a WINS, it assigns sequential numbers to the other WINS.
Note: The table is static for now. We might change it to be a dynamic one
later.
*/
/*
PushPnrVersNoTbl
This table stores the Max. version number pertaining to each WINS server
owning entries in the database of Push Partners
Note: The table is static for now. We might change it to be a dynamic one
later.
*/
#if 0
extern VERS_NO_T pPushPnrVersNoTbl;
#endif
/*
OwnerVersNo -- this array stores the maximum version number for each
owner in the local database
This is used by HandleAddVersMapReq() in RplPush.c
*/
extern VERS_NO_T pRplOwnerVersNo;
extern HANDLE RplSyncWTcpThdEvtHdl; //Sync up with the TCP thread
//
// critical section to guard the RplPullOwnerVersNo array
//
extern CRITICAL_SECTION RplVersNoStoreCrtSec;
/*
typedef definitions
*/
/*
The different types of records that can be read from the registry
*/
typedef enum _RPL_RR_TYPE_E {
RPL_E_PULL = 0, // pull record
RPL_E_PUSH, //push record
RPL_E_QUERY //query record
} RPL_RR_TYPE_E, *PRPL_RR_TYPE_E;
typedef struct _RPL_VERS_NOS_T {
VERS_NO_T VersNo;
VERS_NO_T StartVersNo;
} RPL_VERS_NOS_T, *PRPL_VERS_NOS_T;
/*
RPL_CONFIG_REC_T -- Configuration record for the WINS replicator. It
specifies the Pull/Push/Query partner and associated
parameters
NOTE NOTE NOTE: Keep the datatype of UpdateCount and TimeInterval the same
(see LnkWSameMetricRecs)
*/
typedef struct _RPL_CONFIG_REC_T {
DWORD MagicNo; //Same as that in WinsCnf
COMM_ADD_T WinsAdd; /*address of partner */
LPVOID pWinsCnf; //back pointer to the old WINS struct
LONG TimeInterval; /*time interval in secs for pulling or
* pushing */
BOOL fSpTime; //indicates whether pull/push
//replication should be done at
// a specific time
LONG SpTimeIntvl; //Number of secs to specific time
LONG UpdateCount; /*Count of updates after which
*notification will be sent (applies
*only to Push RR types*/
DWORD RetryCount; //No of retries done
DWORD RetryAfterThisManyRpl; //Retry after this many rpl
//time intervals have elapsed
//from the time we stopped
//replicating due to RetryCount
//hitting the limit
time_t LastCommFailTime; //time of last comm. failure
time_t LastRplTime; //time of last replication
#if PRSCONN
time_t LastCommTime; //time of last comm.
#endif
DWORD PushNtfTries; //No of tries for establishing
//comm. in the past few minutes
//
// The two counters below have to 32 bit aligned otherwise
// the Interlock instructions will fail on x86 MP machines
//
DWORD NoOfRpls; //no of times replication
//happened with this partner
DWORD NoOfCommFails; //no of times replication
//failed due to comm failure
DWORD MemberPrec; //precedence of members of special grp
//relative to other WINS servers
struct _RPL_CONFIG_REC_T *pNext; //ptr to next rec. with same
//time interval (in case of
//of PULL record) or update
//count (in case of PUSH record)
VERS_NO_T LastVersNo; //Only valid for Push records.
//Indicates what the value of the
//local version number counter at the
//time a push notification is sent
DWORD RplType; //type of replication with this guy
BOOL fTemp; //Indicates whether it is a temp
//record that should be deallocated
//after use.
BOOL fLinked; //indicates whether the record is
//is linked to a record before it in
//the buffer of records of the same type //as this record
BOOL fOnlyDynRecs; //indicates whether only dynamic
//records should be pulled/pushed
RPL_RR_TYPE_E RRTyp_e; /*Type of record PULL/PUSH/QUERY*/
#if MCAST > 0
BOOL fSelfFnd; //indicates whether this record was self found
#endif
#if PRSCONN
BOOL fPrsConn;
COMM_HDL_T PrsDlgHdl;
#endif
} RPL_CONFIG_REC_T, *PRPL_CONFIG_REC_T;
/*
RPL_ADD_VERS_NO_T - stores the highest version No. pertaining to an owner
in the directory.
Used by GetVersNo and RplMsgUfrmAddVersMapRsp
*/
typedef struct _RPL_ADD_VERS_NO_T {
COMM_ADD_T OwnerWinsAdd;
VERS_NO_T VersNo;
VERS_NO_T StartVersNo;
} RPL_ADD_VERS_NO_T, *PRPL_ADD_VERS_NO_T;
/*
RPL_PUSHPNR_VERS_NO_T -- stores the Push Pnr Id, the id. of the owner whose
records should be pulled, and the max version
number of these records
This structure is initializes at replication time. The PULL thread
looks at this structure and sends requests to its Push partners to
pull records.
This structure is used by functions in the rplpull.c and rplmsgf.c
modules.
*/
typedef struct _RPL_PUSHPNR_VERS_NO_T {
DWORD PushPnrId;
DWORD OwnerId;
VERS_NO_T MaxVersNo;
} RPL_PUSHPNR_VERS_NO_T, *PRPL_PUSHPNR_VERS_NO_T;
FUTURES("Use NmsDbRowInfo struture")
/*
RPL_REC_ENTRY_T -- structure that holds a record in the range
Min version no - Max version no for an owner WINS
Used by RplPushHandleSndEntriesReq
Size of this structure is 68 bytes
*/
typedef struct _RPL_REC_ENTRY_T {
DWORD NameLen;
DWORD NoOfAdds;
union {
PCOMM_ADD_T pNodeAdd;
COMM_ADD_T NodeAdd[2];
};
VERS_NO_T VersNo;
DWORD TimeStamp; //used only when doing scavenging
DWORD NewTimeStamp; //used only when doing scavenging
BOOL fScv; //used only when doing scavenging
BOOL fGrp;
LPBYTE pName;
DWORD Flag;
} RPL_REC_ENTRY_T, *PRPL_REC_ENTRY_T;
// this struct is same as above plus has the ownerid.
// winsgetdatarecsbyname routine needs to know the ownerid of each
// record and so this new structure is created.
typedef struct _RPL_REC_ENTRY2_T {
DWORD NameLen;
DWORD NoOfAdds;
union {
PCOMM_ADD_T pNodeAdd;
COMM_ADD_T NodeAdd[2];
};
VERS_NO_T VersNo;
DWORD TimeStamp; //used only when doing scavenging
DWORD NewTimeStamp; //used only when doing scavenging
BOOL fScv; //used only when doing scavenging
BOOL fGrp;
LPBYTE pName;
DWORD Flag;
DWORD OwnerId;
} RPL_REC_ENTRY2_T, *PRPL_REC_ENTRY2_T;
//
// Argument to GetReplicas, EstablishComm (both in rplpull.c), and
// WinsCnfGetNextCnfRec to indicate to it how it should traverse
// the buffer of Configuration records
//
typedef enum _RPL_REC_TRAVERSAL_E {
RPL_E_VIA_LINK = 0,
RPL_E_IN_SEQ,
RPL_E_NO_TRAVERSAL
} RPL_REC_TRAVERSAL_E, *PRPL_REC_TRAVERSAL_E;
/*
function declarations
*/
extern
STATUS
ERplInit(
VOID
);
extern
STATUS
ERplInsertQue(
WINS_CLIENT_E Client_e,
QUE_CMD_TYP_E CmdTyp_e,
PCOMM_HDL_T pDlgHdl,
MSG_T pMsg,
MSG_LEN_T MsgLen,
LPVOID pClientCtx,
DWORD MagicNo
);
extern
STATUS
RplFindOwnerId (
IN PCOMM_ADD_T pWinsAdd,
IN OUT LPBOOL pfAllocNew,
OUT DWORD UNALIGNED *pOwnerId,
IN DWORD InitpAction_e,
IN DWORD MemberPrec
);
extern
VOID
ERplPushProc(
BOOL fAddDiff,
LPVOID pCtx,
PCOMM_ADD_T pNoPushWins1,
PCOMM_ADD_T pNoPushWins2
);
extern
PRPL_CONFIG_REC_T
RplGetConfigRec(
RPL_RR_TYPE_E TypeOfRec_e,
PCOMM_HDL_T pDlgHdl,
PCOMM_ADD_T pAdd
);
#if 0
extern
VOID
ERplPushCompl(
PCOMM_ADD_T pNoPushWins
);
#endif
#endif //_RPL_