284 lines
7.2 KiB
C
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
|