Windows2003-3790/inetsrv/iis/staxinc/dnsreci.h
2020-09-30 16:53:55 +02:00

284 lines
7.2 KiB
C++

/*++
Copyright (c) 1996 Microsoft Corporation
Module Name :
dnsrec.h
Abstract:
This file contains type definitions for async DNS
Author:
Rohan Phillips (Rohanp) June-19-1998
Revision History:
--*/
# ifndef _ADNS_STRUCT_HXX_
# define _ADNS_STRUCT_HXX_
#define TCP_REG_LIST_SIGNATURE 'TgeR'
#define DNS_FLAGS_NONE 0x0
#define DNS_FLAGS_TCP_ONLY 0x1
#define DNS_FLAGS_UDP_ONLY 0x2
#define SMTP_MAX_DNS_ENTRIES 100
typedef void (WINAPI * USERDELETEFUNC) (PVOID);
//-----------------------------------------------------------------------------
//
// Description:
// Encapsulates a list of IP addresses (for DNS servers) and maintains
// state information on them... whether the servers are up or down, and
// provides retry logic for down servers.
//
// Some member functions to control the state-tracking logic and error-
// logging are listed as pure virtual functions (see the bottom of this
// class declaration). To use this class, derive from it and implement
// those functions.
//-----------------------------------------------------------------------------
class CDnsServerList
{
protected:
typedef enum _SERVER_STATE
{
DNS_STATE_DOWN = 0,
DNS_STATE_UP,
DNS_STATE_PROBATION
}
SERVER_STATE;
DWORD m_dwSig;
int m_cUpServers;
PIP_ARRAY m_IpListPtr;
DWORD *m_prgdwFailureTick;
SERVER_STATE *m_prgServerState;
DWORD *m_prgdwFailureCount;
DWORD *m_prgdwConnections;
CShareLockNH m_sl;
public:
CDnsServerList();
~CDnsServerList();
BOOL Update(PIP_ARRAY IpPtr);
BOOL UpdateIfChanged(PIP_ARRAY IpPtr);
DWORD GetWorkingServerIp(DWORD *dwIp, BOOL fThrottle);
void MarkDown(DWORD dwIp, DWORD dwErr, BOOL fUdp);
void ResetTimeoutServersIfNeeded();
void ResetServerOnConnect(DWORD dwIp);
BOOL CopyList(PIP_ARRAY *ppipArray);
DWORD GetCount()
{
DWORD dwCount;
m_sl.ShareLock();
dwCount = m_IpListPtr ? m_IpListPtr->cAddrCount : 0;
m_sl.ShareUnlock();
return dwCount;
}
DWORD GetUpServerCount()
{
DWORD dwCount;
m_sl.ShareLock();
dwCount = m_cUpServers;
m_sl.ShareUnlock();
return dwCount;
}
DWORD GetAnyServerIp(PDWORD pdwIp)
{
m_sl.ShareLock();
if(!m_IpListPtr || 0 == m_IpListPtr->cAddrCount) {
m_sl.ShareUnlock();
return DNS_ERROR_NO_DNS_SERVERS;
}
*pdwIp = m_IpListPtr->aipAddrs[0];
m_sl.ShareUnlock();
return ERROR_SUCCESS;
}
BOOL AllowConnection(DWORD iServer)
{
// Note: Sharelock must have been acquired by caller
if(m_prgServerState[iServer] == DNS_STATE_UP)
return TRUE;
if(m_prgServerState[iServer] == DNS_STATE_PROBATION &&
m_prgdwConnections[iServer] < ConnectsAllowedInProbation())
{
m_prgdwConnections[iServer]++;
return TRUE;
}
return FALSE;
}
//
// Pure virtual methods to be overridden by a class to implement processing
// specific to the application/component.
//
virtual DWORD ConnectsAllowedInProbation() = 0;
virtual DWORD ErrorsBeforeFailover() = 0;
virtual void LogServerDown(
DWORD dwServerIp,
BOOL fUdp,
DWORD dwErr,
DWORD cUpServers) = 0;
};
//-----------------------------------------------------------------------------
// Description:
// This class adds SMTP DNS specific error-controls and error-logging to
// the generic DNS server state tracking class.
//-----------------------------------------------------------------------------
class CTcpRegIpList : public CDnsServerList
{
public:
DWORD ConnectsAllowedInProbation();
DWORD ErrorsBeforeFailover();
void LogServerDown(
DWORD dwServerIp,
BOOL fUdp,
DWORD dwErr,
DWORD cUpServers);
};
typedef struct _MXIPLISTENTRY_
{
DWORD IpAddress;
LIST_ENTRY ListEntry;
}MXIPLIST_ENTRY, *PMXIPLIST_ENTRY;
typedef struct _MX_NAMES_
{
char DnsName[MAX_INTERNET_NAME];
DWORD NumEntries;
LIST_ENTRY IpListHead;
}MX_NAMES, *PMX_NAMES;
typedef struct _SMTPDNS_REC_
{
DWORD NumRecords; //number of record in DnsArray
DWORD StartRecord; //the starting index
PVOID pMailMsgObj; //pointer to a mailmsg obj
PVOID pAdvQContext;
PVOID pRcptIdxList;
DWORD dwNumRcpts;
MX_NAMES *DnsArray[SMTP_MAX_DNS_ENTRIES];
} SMTPDNS_RECS, *PSMTPDNS_RECS;
class CDnsLogger
{
public:
virtual void DnsPrintfMsg(char *szFormat, ...) = 0;
virtual void DnsPrintfErr(char *szFormat, ...) = 0;
virtual void DnsPrintfDbg(char *szFormat, ...) = 0;
virtual void DnsLogAsyncQuery(
char *pszQuestionName,
WORD wQuestionType,
DWORD dwSmtpFlags,
BOOL fUdp,
CDnsServerList *pDnsServerList) = 0;
virtual void DnsLogApiQuery(
char *pszQuestionName,
WORD wQuestionType,
DWORD dwDnsApiFlags,
BOOL fGlobal,
PIP_ARRAY pipServers) = 0;
virtual void DnsLogResponse(
DWORD dwStatus,
PDNS_RECORD pDnsRecordList,
PBYTE pbMsg,
DWORD dwMessageLength) = 0;
virtual void DnsPrintRecord(PDNS_RECORD pDnsRecord) = 0;
};
extern CDnsLogger *g_pDnsLogger;
// The following are defined as macros since they wrap functions that
// take a variable number of arguments
#define DNS_PRINTF_MSG \
if(g_pDnsLogger) \
g_pDnsLogger->DnsPrintfMsg
#define DNS_PRINTF_ERR \
if(g_pDnsLogger) \
g_pDnsLogger->DnsPrintfErr
#define DNS_PRINTF_DBG \
if(g_pDnsLogger) \
g_pDnsLogger->DnsPrintfDbg
inline void DNS_LOG_ASYNC_QUERY(
IN DNS_NAME pszQuestionName,
IN WORD wQuestionType,
IN DWORD dwSmtpFlags,
IN BOOL fUdp,
IN CDnsServerList *pDnsServerList)
{
if(g_pDnsLogger)
{
g_pDnsLogger->DnsLogAsyncQuery(pszQuestionName,
wQuestionType, dwSmtpFlags, fUdp, pDnsServerList);
}
}
inline void DNS_LOG_API_QUERY(
IN DNS_NAME pszQuestionName,
IN WORD wQuestionType,
IN DWORD dwDnsApiFlags,
IN BOOL fGlobal,
IN PIP_ARRAY pipServers)
{
if(g_pDnsLogger)
{
g_pDnsLogger->DnsLogApiQuery(pszQuestionName,
wQuestionType, dwDnsApiFlags, fGlobal, pipServers);
}
}
inline void DNS_LOG_RESPONSE(
IN DWORD dwStatus,
IN PDNS_RECORD pDnsRecordList,
PBYTE pbMsg,
DWORD dwMessageLength)
{
if(g_pDnsLogger)
{
g_pDnsLogger->DnsLogResponse(dwStatus,
pDnsRecordList, pbMsg, dwMessageLength);
}
}
inline void DNS_PRINT_RECORD(
IN PDNS_RECORD pDnsRecord)
{
if(g_pDnsLogger)
g_pDnsLogger->DnsPrintRecord(pDnsRecord);
}
#endif