#ifndef __CRefTable_h__
#define __CRefTable_h__ 1
#include "DirServicesTypes.h"
#include "CObject.h"
#include <dispatch/dispatch.h>
#include <map>
#include <vector>
#include <string>
#include <netinet/in.h>
using namespace std;
class CServerPlugin;
enum eRefType {
eRefTypeDir = 0x01,
eRefTypeDirNode = 0x02,
eRefTypeRecord = 0x03,
eRefTypeAttributeList = 0x04,
eRefTypeAttributeValueList = 0x05,
};
typedef SInt32 RefDeallocateProc ( UInt32 inRefNum, eRefType inRefType, CServerPlugin *inPluginPtr );
enum eSubType {
eSubTypeDefault = 0x00,
eSubTypeTCP = 0xC0, eSubTypeCSBP = 0x30, };
#define kRefTypeMask 0xff000000
#define kSubTypeMask 0x00ff0000
#define kIndexMask 0x0000ffff
struct sRefEntry;
struct sClientEntry;
class CRefTable;
typedef map<UInt32, sRefEntry *> tRefToEntry;
typedef map<UInt32, sRefEntry *>::iterator tRefToEntryI;
typedef map<UInt32, sClientEntry *> tRefToClientEntry;
typedef map<UInt32, sClientEntry *>::iterator tRefToClientEntryI;
typedef map<mach_port_t, sClientEntry *> tMachPortToClientEntry;
typedef map<mach_port_t, sClientEntry *>::iterator tMachPortToClientEntryI;
typedef map<int, sClientEntry *> tPortToClientEntry;
typedef map<int, sClientEntry *>::iterator tPortToClientEntryI;
struct sRefEntry : public CObject<sRefEntry>
{
UInt32 fRefNum;
UInt32 fParentID;
CServerPlugin *fPlugin;
char *fNodeName; tRefToEntry fSubRefs;
CRefTable *fRefTable;
public:
sRefEntry( void );
protected:
virtual ~sRefEntry( void );
};
union uClientID
{
union {
sockaddr_in ipV4;
sockaddr_in6 ipV6;
sockaddr_storage storage;
} fAddress; pid_t fPID; };
union uPortInfo
{
int fSocket; mach_port_t fMachPort; };
struct sClientEntry : public CObject<sClientEntry>
{
int32_t fFlags;
tRefToEntry fSubRefs;
uClientID clientID;
uPortInfo portInfo;
CRefTable *fRefTable;
public:
sClientEntry( void );
void ClearChildRefs( void );
protected:
virtual ~sClientEntry( void );
};
#define kClientTypeMach 0x00000001
#define kClientTypeTCP 0x00000002
struct tClientDetails
{
int32_t flags;
uClientID clientID;
uPortInfo portInfo;
vector<UInt32> refs;
};
inline eRefType GetRefType( UInt32 inRefNum ) { return (eRefType) ((inRefNum & kRefTypeMask) >> 24); }
int GetClientIPString( sockaddr *clientIP, char *clientIP, size_t client_size );
class CRefTable {
public:
dispatch_queue_t fCleanupQueue;
CRefTable ( RefDeallocateProc *deallocProc );
~CRefTable ( void );
tDirStatus CreateReference ( UInt32 *outRef, eRefType inType, CServerPlugin *inPlugin, UInt32 inParentID, pid_t inPID, mach_port_t inMachPort,
sockaddr *inAddress = NULL, int inSocket = 0, const char *inNodeName = NULL );
tDirStatus RemoveReference ( UInt32 inRef, eRefType inRefType, mach_port_t inMachPort, int inSocket );
void RemoveReference ( UInt32 inRef );
tDirStatus VerifyReference ( UInt32 inRef, eRefType inRefType, CServerPlugin **outPlugin, mach_port_t inMachPort, int inSocket );
char * CopyNodeRefName ( tDirNodeReference inDirNodeRef );
tDirStatus SetNodePluginPtr ( tDirNodeReference inNodeRef, CServerPlugin *inPlugin );
CServerPlugin *GetPluginForRef ( UInt32 inRef );
void CleanRefsForSocket ( int inSocket );
void CleanRefsForMachRefs( mach_port_t inMachPort );
void CleanRefsForPlugin ( CServerPlugin *inPlugin, dispatch_block_t completeBlock );
vector<string> *GetClientPIDListStrings ( void );
vector<tClientDetails> *GetClientDetails ( mach_port_t inMachPort = -1, int inSocket = -1 );
inline dispatch_queue_t GetQueue(void) { return fQueue; }
inline RefDeallocateProc *GetDeallocProc(void) { return fDeallocProc; }
private:
sRefEntry *GetRefEntry ( UInt32 inRef );
static void RemoveReference ( void *inContext );
private:
RefDeallocateProc *fDeallocProc;
tMachPortToClientEntry fMachPortToClientEntry;
tPortToClientEntry fPortToClientEntry;
tRefToEntry fRefToEntry;
tRefToClientEntry fRefToClientEntry;
uint16_t fNextIndex;
dispatch_queue_t fQueue;
};
#endif