#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_