windows-nt/Source/XPSP1/NT/base/cluster/clusnet/xport/cnpdef.h
2020-09-26 16:20:57 +08:00

766 lines
20 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
cnpdef.h
Abstract:
Main private header file for the Cluster Network Protocol.
Author:
Mike Massa (mikemas) July 29, 1996
Revision History:
Who When What
-------- -------- ----------------------------------------------
mikemas 07-29-96 created
Notes:
--*/
#ifndef _CNPDEF_INCLUDED_
#define _CNPDEF_INCLUDED_
#include <fipsapi.h>
#include <sspi.h>
//
// Forward declarations
//
typedef struct _CNP_INTERFACE *PCNP_INTERFACE;
//
// Priority definitions
//
#define CnpIsHigherPriority(_p1, _p2) ((_p1) < (_p2))
#define CnpIsLowerPriority(_p1, _p2) ((_p1) > (_p2))
#define CnpIsEqualPriority(_p1, _p2) ((_p1) == (_p2))
//
// Multicast Group Object
//
// This structure contains the data needed to implement a multicast
// endpoint on a network.
//
typedef struct _CNP_MULTICAST_GROUP {
ULONG McastNetworkBrand;
PTRANSPORT_ADDRESS McastTdiAddress;
ULONG McastTdiAddressLength;
PVOID Key;
ULONG KeyLength;
DESTable DesTable;
PVOID Salt;
ULONG SaltLength;
ULONG SignatureLength;
ULONG RefCount;
} CNP_MULTICAST_GROUP, *PCNP_MULTICAST_GROUP;
//
// Network Object
//
// This structure represents a communication link between the nodes of a
// cluster. It references a particular transport protocol and interface
// configured on the local system. It also links together all of the
// interface objects for the nodes attached to the network.
//
// Networks are identified by a small integer assigned by the Cluster
// Service. Network objects are stored in a global array indexed by
// the network ID.
//
typedef struct {
LIST_ENTRY Linkage;
CN_SIGNATURE_FIELD
CL_NETWORK_ID Id;
CN_LOCK Lock;
CN_IRQL Irql;
ULONG RefCount;
ULONG ActiveRefCount;
CLUSNET_NETWORK_STATE State;
ULONG Flags;
ULONG Priority;
HANDLE DatagramHandle;
PFILE_OBJECT DatagramFileObject;
PDEVICE_OBJECT DatagramDeviceObject;
TDI_PROVIDER_INFO ProviderInfo;
PIRP PendingDeleteIrp;
PIRP PendingOfflineIrp;
WORK_QUEUE_ITEM ExWorkItem;
PCNP_MULTICAST_GROUP CurrentMcastGroup;
PCNP_MULTICAST_GROUP PreviousMcastGroup;
CX_CLUSTERSCREEN McastReachableNodes;
ULONG McastReachableCount;
} CNP_NETWORK, *PCNP_NETWORK;
#define CNP_NETWORK_SIG 'kwtn'
extern LIST_ENTRY CnpNetworkList;
extern CN_LOCK CnpNetworkListLock;
#define CNP_NET_FLAG_DELETING 0x00000001
#define CNP_NET_FLAG_PARTITIONED 0x00000002
#define CNP_NET_FLAG_RESTRICTED 0x00000004
#define CNP_NET_FLAG_LOCALDISCONN 0x00000008
#define CNP_NET_FLAG_MULTICAST 0x00000010
#define CNP_NET_FLAG_MCASTSORTED 0x00000020
#define CnpIsNetworkDeleting(_network) \
(((_network)->Flags & CNP_NET_FLAG_DELETING) != 0)
#define CnpIsValidNetworkId(_id) ( ((_id) != ClusterAnyNetworkId ) && \
((_id) != ClusterInvalidNetworkId))
#define CnpIsNetworkRestricted(_network) \
(((_network)->Flags & CNP_NET_FLAG_RESTRICTED) != 0)
#define CnpIsNetworkLocalDisconn(_network) \
(((_network)->Flags & CNP_NET_FLAG_LOCALDISCONN) != 0)
#define CnpIsNetworkMulticastCapable(_network) \
(((_network)->Flags & CNP_NET_FLAG_MULTICAST) != 0)
#define CnpIsNetworkMulticastSorted(_network) \
(((_network)->Flags & CNP_NET_FLAG_MCASTSORTED) != 0)
#define CnpNetworkResetMcastReachableNodes(_network) \
(RtlZeroMemory( \
&((_network)->McastReachableNodes), \
sizeof((_network)->McastReachableNodes) \
))
/*
(BYTE((_network)->McastReachableNodes, INT_NODE(CnLocalNodeId)) \
= (1 << (BYTEL-1-BIT(INT_NODE(CnLocalNodeId)))))
*/
//
// Node Object
//
// This structure represents a cluster node. One exists for each
// defined member of a cluster.
//
// Nodes are identified by a small integer assigned by the Cluster Service.
// Node objects are stored in a global array indexed by node ID.
//
// Note that the order of the CLUSTER_NODE_COMM_STATE enumeration *is* important.
//
typedef struct {
LIST_ENTRY Linkage;
CN_SIGNATURE_FIELD
CL_NODE_ID Id;
CN_LOCK Lock;
CN_IRQL Irql;
ULONG RefCount;
CLUSNET_NODE_COMM_STATE CommState;
CLUSNET_NODE_STATE MMState;
ULONG Flags;
LIST_ENTRY InterfaceList;
PCNP_INTERFACE CurrentInterface;
PIRP PendingDeleteIrp;
BOOLEAN HBWasMissed;
BOOLEAN NodeDownIssued;
ULONG MissedHBs;
} CNP_NODE, *PCNP_NODE;
#define CNP_NODE_SIG 'edon'
extern PCNP_NODE * CnpNodeTable;
extern CN_LOCK CnpNodeTableLock;
extern PCNP_NODE CnpLocalNode;
#define CNP_NODE_FLAG_DELETING 0x00000001
#define CNP_NODE_FLAG_UNREACHABLE 0x00000002
#define CNP_NODE_FLAG_LOCAL 0x00000010
#define CnpIsNodeDeleting(_node) \
((_node)->Flags & CNP_NODE_FLAG_DELETING)
#define CnpIsNodeLocal(_node) \
((_node)->Flags & CNP_NODE_FLAG_LOCAL)
#define CnpIsNodeUnreachable(_node) \
((_node)->Flags & CNP_NODE_FLAG_UNREACHABLE)
//++
//
// Routine Description:
//
// Callback routine for CnpWalkNodeTable. Performs an operation on
// the specified node.
//
// Arguments:
//
// UpdateNode - A pointer to the node on which to operate.
//
// UpdateContext - Operation-specific context
//
// NodeTableIrql - The IRQL at which the CnpNodeTableLock was acquired.
//
// Return Value:
//
// Returns TRUE if the CnpNodeTable lock is still held.
// Returns FALSE if the CnpNodeTable lock is released.
//
// Notes:
//
// Called with both the CnpNodeTable and node object locks held.
// The node object lock is released upon return.
//
//--
typedef
BOOLEAN
(*PCNP_NODE_UPDATE_ROUTINE)(
IN PCNP_NODE UpdateNode,
IN PVOID UpdateContext,
IN CN_IRQL NodeTableIrql
);
//
// Interface Object
//
// This structure represents a node's transport interface to a network.
// It contains a transport address which may be used to communicate
// with the specified node using the specified network.
//
// Interface objects are linked onto lists in the associated node objects.
// They are identified by a {node, network} tuple.
//
// The interfaces on a node are ranked based on their state and priority.
// Numerically higher state values are ranked ahead of lower values.
// For interfaces with the same state, Numerically lower priority values
// are ranked ahead of lower values. Priority values fall in the range
// 0x1-0xFFFFFFFF. State values are defined by CLUSNET_INTERFACE_STATE
// enumeration. By default, interfaces inherit their priority from the
// associated network. In this case, the Priority field will contain the
// network's priority value, and the CNP_IF_FLAG_USE_NETWORK_PRIORITY flag
// will be set in the Flags field.
//
// Note that the order of the CLUSNET_INTERFACE_STATE enumeration
// *is* important.
//
typedef struct _CNP_INTERFACE {
LIST_ENTRY NodeLinkage;
CN_SIGNATURE_FIELD
PCNP_NODE Node;
PCNP_NETWORK Network;
CLUSNET_INTERFACE_STATE State;
ULONG Priority;
ULONG Flags;
ULONG MissedHBs;
ULONG SequenceToSend;
ULONG LastSequenceReceived;
ULONG McastDiscoverCount;
ULONG McastRediscoveryCountdown;
ULONG AdapterWMIProviderId;
ULONG TdiAddressLength;
TRANSPORT_ADDRESS TdiAddress;
} CNP_INTERFACE;
#define CNP_INTERFACE_SIG ' fi'
#define CNP_INTERFACE_MCAST_DISCOVERY 0x5
#define CNP_INTERFACE_MCAST_REDISCOVERY 3000 // 1 hr at 1.2 hbs/sec
#define CNP_IF_FLAG_USE_NETWORK_PRIORITY 0x00000001
#define CNP_IF_FLAG_RECVD_MULTICAST 0x00000002
#define CnpIsInterfaceUsingNetworkPriority(_if) \
( (_if)->Flags & CNP_IF_FLAG_USE_NETWORK_PRIORITY )
#define CnpInterfaceQueryReceivedMulticast(_if) \
( (_if)->Flags & CNP_IF_FLAG_RECVD_MULTICAST )
#define CnpInterfaceSetReceivedMulticast(_if) \
( (_if)->Flags |= CNP_IF_FLAG_RECVD_MULTICAST )
#define CnpInterfaceClearReceivedMulticast(_if) \
( (_if)->Flags &= ~CNP_IF_FLAG_RECVD_MULTICAST )
//++
//
// Routine Description:
//
// Callback routine for CnpWalkInterfacesOnNetwork and
// CnpWalkInterfacesOnNode routines. Performs a specified
// operation on all interfaces.
//
// Arguments:
//
// UpdateInterface - A pointer to the interface on which to operate.
//
// Return Value:
//
// None.
//
// Notes:
//
// Called with the associated node and network object locks held.
// Mut return with the network object lock released.
// May not release node object lock at any time.
//
//--
typedef
VOID
(*PCNP_INTERFACE_UPDATE_ROUTINE)(
IN PCNP_INTERFACE UpdateInterface
);
//
// Send Request Pool
//
typedef struct {
USHORT UpperProtocolHeaderLength;
ULONG UpperProtocolContextSize;
UCHAR UpperProtocolNumber;
UCHAR CnpVersionNumber;
UCHAR Pad[2];
} CNP_SEND_REQUEST_POOL_CONTEXT, *PCNP_SEND_REQUEST_POOL_CONTEXT;
//
// Forward Declaration
//
typedef struct _CNP_SEND_REQUEST *PCNP_SEND_REQUEST;
typedef
VOID
(*PCNP_SEND_COMPLETE_ROUTINE)(
IN NTSTATUS Status,
IN OUT PULONG BytesSent,
IN PCNP_SEND_REQUEST SendRequest,
IN PMDL DataMdl
);
//
// Send Request Structure
//
typedef struct _CNP_SEND_REQUEST {
CN_RESOURCE CnResource;
PMDL HeaderMdl;
PVOID CnpHeader;
PIRP UpperProtocolIrp;
PVOID UpperProtocolHeader;
USHORT UpperProtocolHeaderLength;
KPROCESSOR_MODE UpperProtocolIrpMode;
UCHAR Pad;
PMDL UpperProtocolMdl;
PVOID UpperProtocolContext;
PCNP_SEND_COMPLETE_ROUTINE CompletionRoutine;
PCNP_NETWORK Network;
PCNP_MULTICAST_GROUP McastGroup;
TDI_CONNECTION_INFORMATION TdiSendDatagramInfo;
} CNP_SEND_REQUEST;
//
// Internal Init/Cleanup routines
//
//
// Internal Node Routines
//
VOID
CnpWalkNodeTable(
PCNP_NODE_UPDATE_ROUTINE UpdateRoutine,
PVOID UpdateContext
);
NTSTATUS
CnpValidateAndFindNode(
IN CL_NODE_ID NodeId,
OUT PCNP_NODE * Node
);
PCNP_NODE
CnpLockedFindNode(
IN CL_NODE_ID NodeId,
IN CN_IRQL NodeTableIrql
);
PCNP_NODE
CnpFindNode(
IN CL_NODE_ID NodeId
);
VOID
CnpOfflineNode(
PCNP_NODE Node
);
VOID
CnpDeclareNodeUnreachable(
PCNP_NODE Node
);
VOID
CnpDeclareNodeReachable(
PCNP_NODE Node
);
VOID
CnpReferenceNode(
PCNP_NODE Node
);
VOID
CnpDereferenceNode(
PCNP_NODE Node
);
//
// Internal Network Routines
//
VOID
CnpReferenceNetwork(
PCNP_NETWORK Network
);
VOID
CnpDereferenceNetwork(
PCNP_NETWORK Network
);
VOID
CnpActiveReferenceNetwork(
PCNP_NETWORK Network
);
VOID
CnpActiveDereferenceNetwork(
PCNP_NETWORK Network
);
PCNP_NETWORK
CnpFindNetwork(
IN CL_NETWORK_ID NetworkId
);
VOID
CnpDeleteNetwork(
PCNP_NETWORK Network,
CN_IRQL NetworkListIrql
);
VOID
CnpFreeMulticastGroup(
IN PCNP_MULTICAST_GROUP Group
);
#define CnpReferenceMulticastGroup(_group) \
(InterlockedIncrement(&((_group)->RefCount)))
#define CnpDereferenceMulticastGroup(_group) \
if (InterlockedDecrement(&((_group)->RefCount)) == 0) { \
CnpFreeMulticastGroup(_group); \
}
BOOLEAN
CnpSortMulticastNetwork(
IN PCNP_NETWORK Network,
IN BOOLEAN RaiseEvent,
OUT CX_CLUSTERSCREEN * McastReachableNodes OPTIONAL
);
BOOLEAN
CnpMulticastChangeNodeReachability(
IN PCNP_NETWORK Network,
IN PCNP_NODE Node,
IN BOOLEAN Reachable,
IN BOOLEAN RaiseEvent,
OUT CX_CLUSTERSCREEN * NewMcastReachableNodes OPTIONAL
);
PCNP_NETWORK
CnpGetBestMulticastNetwork(
VOID
);
//
// Internal Interface Routines
//
VOID
CnpWalkInterfacesOnNode(
PCNP_NODE Node,
PCNP_INTERFACE_UPDATE_ROUTINE UpdateRoutine
);
VOID
CnpWalkInterfacesOnNetwork(
PCNP_NETWORK Network,
PCNP_INTERFACE_UPDATE_ROUTINE UpdateRoutine
);
NTSTATUS
CnpOnlinePendingInterface(
PCNP_INTERFACE Interface
);
VOID
CnpOnlinePendingInterfaceWrapper(
PCNP_INTERFACE Interface
);
NTSTATUS
CnpOfflineInterface(
PCNP_INTERFACE Interface
);
VOID
CnpOfflineInterfaceWrapper(
PCNP_INTERFACE Interface
);
NTSTATUS
CnpOnlineInterface(
PCNP_INTERFACE Interface
);
NTSTATUS
CnpFailInterface(
PCNP_INTERFACE Interface
);
VOID
CnpDeleteInterface(
IN PCNP_INTERFACE Interface
);
VOID
CnpReevaluateInterfaceRole(
IN PCNP_INTERFACE Interface
);
VOID
CnpRecalculateInterfacePriority(
IN PCNP_INTERFACE Interface
);
VOID
CnpUpdateNodeCurrentInterface(
PCNP_NODE Node
);
VOID
CnpResetAndOnlinePendingInterface(
IN PCNP_INTERFACE Interface
);
NTSTATUS
CnpFindInterface(
IN CL_NODE_ID NodeId,
IN CL_NETWORK_ID NetworkId,
OUT PCNP_INTERFACE * Interface
);
//
// Send Routines.
//
PCN_RESOURCE_POOL
CnpCreateSendRequestPool(
IN UCHAR CnpVersionNumber,
IN UCHAR UpperProtocolNumber,
IN USHORT UpperProtocolHeaderSize,
IN USHORT UpperProtocolContextSize,
IN USHORT PoolDepth
);
#define CnpDeleteSendRequestPool(_pool) \
{ \
CnDrainResourcePool(_pool); \
CnFreePool(_pool); \
}
NTSTATUS
CnpSendPacket(
IN PCNP_SEND_REQUEST SendRequest,
IN CL_NODE_ID DestNodeId,
IN PMDL DataMdl,
IN USHORT DataLength,
IN BOOLEAN CheckDestState,
IN CL_NETWORK_ID NetworkId OPTIONAL
);
VOID
CcmpSendPoisonPacket(
IN PCNP_NODE Node,
IN PCX_SEND_COMPLETE_ROUTINE CompletionRoutine, OPTIONAL
IN PVOID CompletionContext, OPTIONAL
IN PCNP_NETWORK Network, OPTIONAL
IN PIRP Irp OPTIONAL
);
//
// Receive Routines
//
NTSTATUS
CcmpReceivePacketHandler(
IN PCNP_NETWORK Network,
IN CL_NODE_ID SourceNodeId,
IN ULONG CnpReceiveFlags,
IN ULONG TdiReceiveDatagramFlags,
IN ULONG BytesIndicated,
IN ULONG BytesAvailable,
OUT PULONG BytesTaken,
IN PVOID Tsdu,
OUT PIRP * Irp
);
VOID
CnpReceiveHeartBeatMessage(
IN PCNP_NETWORK Network,
IN CL_NODE_ID SourceNodeId,
IN ULONG SeqNumber,
IN ULONG AckNumber,
IN BOOLEAN Multicast
);
VOID
CnpReceivePoisonPacket(
IN PCNP_NETWORK Network,
IN CL_NODE_ID SourceNodeId,
IN ULONG SeqNumber
);
//
// TDI routines
//
NTSTATUS
CnpTdiReceiveDatagramHandler(
IN PVOID TdiEventContext,
IN LONG SourceAddressLength,
IN PVOID SourceAddress,
IN LONG OptionsLength,
IN PVOID Options,
IN ULONG ReceiveDatagramFlags,
IN ULONG BytesIndicated,
IN ULONG BytesAvailable,
OUT PULONG BytesTaken,
IN PVOID Tsdu,
OUT PIRP * IoRequestPacket
);
NTSTATUS
CnpTdiErrorHandler(
IN PVOID TdiEventContext,
IN NTSTATUS Status
);
NTSTATUS
CnpTdiSetEventHandler(
IN PFILE_OBJECT FileObject,
IN PDEVICE_OBJECT DeviceObject,
IN ULONG EventType,
IN PVOID EventHandler,
IN PVOID EventContext,
IN PIRP ClientIrp OPTIONAL
);
NTSTATUS
CnpIssueDeviceControl (
IN PFILE_OBJECT FileObject,
IN PDEVICE_OBJECT DeviceObject,
IN PVOID IrpParameters,
IN ULONG IrpParametersLength,
IN PVOID MdlBuffer,
IN ULONG MdlBufferLength,
IN UCHAR MinorFunction,
IN PIRP ClientIrp OPTIONAL
);
VOID
CnpAttachSystemProcess(
VOID
);
VOID
CnpDetachSystemProcess(
VOID
);
NTSTATUS
CnpOpenDevice(
IN LPWSTR DeviceName,
OUT HANDLE *Handle
);
NTSTATUS
CnpZwDeviceControl(
IN HANDLE Handle,
IN ULONG IoControlCode,
IN PVOID InputBuffer,
IN ULONG InputBufferLength,
IN PVOID OutputBuffer,
IN ULONG OutputBufferLength
);
NTSTATUS
CnpSetTcpInfoEx(
IN HANDLE Handle,
IN ULONG Entity,
IN ULONG Class,
IN ULONG Type,
IN ULONG Id,
IN PVOID Value,
IN ULONG ValueLength
);
#define CnpIsIrpStackSufficient(_irp, _targetdevice) \
((_irp)->CurrentLocation - (_targetdevice)->StackSize >= 1)
#define CnpIsIPv4McastTransportAddress(_ta) \
( (((PTA_IP_ADDRESS)(_ta))->Address[0].AddressType \
== TDI_ADDRESS_TYPE_IP \
) \
&& ((((PTA_IP_ADDRESS)(_ta))->Address[0].Address[0].in_addr \
& 0xf0) \
== 0xe0 \
) \
)
#define CnpIsIPv4McastSameGroup(_ta1, _ta2) \
( ((PTA_IP_ADDRESS)(_ta1))->Address[0].Address[0].in_addr == \
((PTA_IP_ADDRESS)(_ta2))->Address[0].Address[0].in_addr \
)
//
// Signature mechanisms.
//
extern FIPS_FUNCTION_TABLE CxFipsFunctionTable;
// Pad the signature length to be an even multiple of DES_BLOCKLEN.
#define CX_SIGNATURE_LENGTH \
(((A_SHA_DIGEST_LEN % DES_BLOCKLEN) == 0) ? \
A_SHA_DIGEST_LEN : \
A_SHA_DIGEST_LEN + DES_BLOCKLEN - (A_SHA_DIGEST_LEN % DES_BLOCKLEN))
NTSTATUS
CnpSignMulticastMessage(
IN PCNP_SEND_REQUEST SendRequest,
IN PMDL DataMdl,
IN OUT CL_NETWORK_ID * NetworkId,
OUT ULONG * SigLen OPTIONAL
);
NTSTATUS
CnpVerifyMulticastMessage(
IN PCNP_NETWORK Network,
IN PVOID Tsdu,
IN ULONG TsduLength,
IN ULONG ExpectedPayload,
OUT ULONG * BytesTaken,
OUT BOOLEAN * CurrentGroup
);
#endif // ifndef _CNPDEF_INCLUDED_