Windows2003-3790/inetsrv/iis/svcs/smtp/server/remoteq.hxx
2020-09-30 16:53:55 +02:00

243 lines
8.6 KiB
C++

/*++
Copyright (c) 1994 Microsoft Corporation
Module Name :
localq.hxx
Abstract:
This module defines the RemoteQ class
Author:
Rohan Phillips ( Rohanp ) 11-Dec-1995
Project:
SMTP Server DLL
Revision History:
--*/
#ifndef _REMOTE_QUEUE_HXX_
#define _REMOTE_QUEUE_HXX_
/************************************************************
* Include Headers
************************************************************/
/************************************************************
* Symbolic Constants
************************************************************/
#include "asynccon.hxx"
#include <smtpevent.h>
/************************************************************
* Type Definitions
************************************************************/
// X5 189659 intrumentation
extern DWORD g_fCrashOnInvalidSMTPConn;
BOOL AsyncCopyMailToDropDir(
ISMTPConnection *pISMTPConnection,
const char * DropDirectory,
SMTP_SERVER_INSTANCE * pParentInst
);
#define DNS_RESOLVER_RECORD_VALID_SIGNATURE 'uRRD'
#define DNS_RESOLVER_RECORD_INVALID_SIGNATURE 'fRRD'
class DNS_RESOLVER_RECORD;
//
// A wrapper class for iterating through the hosts in the basic dns resolver record
// returned by the dns resolution sink. The wrapper clubs together the index (of the
// current destination host) with the resolver record, as they always are used in
// conjunction.
//
class DNS_RESOLVER_RECORD
{
private:
IDnsResolverRecord *pIDnsResolverRecord;
DWORD iDnsResolverRecord;
CTcpRegIpList *m_pTcpRegIpList;
DWORD m_signature;
public:
DNS_RESOLVER_RECORD()
: pIDnsResolverRecord(NULL),
iDnsResolverRecord(0),
m_pTcpRegIpList(NULL),
m_signature(DNS_RESOLVER_RECORD_VALID_SIGNATURE)
{
TraceFunctEnterEx((LPARAM) this, "DNS_RESOLVER_RECORD::DNS_RESOLVER_RECORD");
DebugTrace((LPARAM) this, "Creating DNS_RESOLVER_RECORD = 0x%08x", this);
}
~DNS_RESOLVER_RECORD()
{
TraceFunctEnterEx((LPARAM) this, "DNS_RESOLVER_RECORD::~DNS_RESOLVER_RECORD");
DebugTrace((LPARAM) this, "Destructing DNS_RESOLVER_RECORD = 0x%08x", this);
if(pIDnsResolverRecord) {
pIDnsResolverRecord->Release();
pIDnsResolverRecord = NULL;
}
m_pTcpRegIpList = NULL;
m_signature = DNS_RESOLVER_RECORD_INVALID_SIGNATURE;
}
void SetDnsResolverRecord(IDnsResolverRecord *pIDns) { pIDnsResolverRecord = pIDns; }
IDnsResolverRecord *GetDnsResolverRecord() { return pIDnsResolverRecord; }
void SetDnsList(CTcpRegIpList *pTcpRegIpList) { m_pTcpRegIpList = pTcpRegIpList; }
CTcpRegIpList *GetDnsList() { return m_pTcpRegIpList; }
void ResetCounter() { iDnsResolverRecord = 0; }
HRESULT HrGetNextDestinationHost(LPSTR *ppszHostName, DWORD *pdwAddr)
{
_ASSERT(pIDnsResolverRecord && "Check with GetDnsResolverRecord first!");
if(!pIDnsResolverRecord)
return E_FAIL;
return pIDnsResolverRecord->GetItem( iDnsResolverRecord++, ppszHostName, pdwAddr );
}
};
class REMOTE_QUEUE : public PERSIST_QUEUE
{
public:
REMOTE_QUEUE(SMTP_SERVER_INSTANCE * pSmtpInst) : PERSIST_QUEUE(pSmtpInst) {};
virtual void BeforeDelete(void){DROP_COUNTER (GetParentInst(), RemoteQueueLength);}
virtual BOOL ProcessQueueEvents(ISMTPConnection *pISMTPConnection);
virtual BOOL InsertEntry(IN OUT PERSIST_QUEUE_ENTRY * pEntry, QUEUE_SIG Qsig = SIGNAL, QUEUE_POSITION Qpos = QUEUE_TAIL)
{
return PERSIST_QUEUE::InsertEntry (pEntry, Qsig, Qpos);
}
virtual PQUEUE_ENTRY PopQEntry(void)
{
//Decrement our counter
DROP_COUNTER(GetParentInst(), RemoteQueueLength);
return PERSIST_QUEUE::PopQEntry ();
}
virtual void DropRetryCounter(void) {DROP_COUNTER(GetParentInst(), RemoteRetryQueueLength);}
virtual void BumpRetryCounter(void) {BUMP_COUNTER(GetParentInst(), RemoteRetryQueueLength);}
virtual DWORD GetRetryMinutes(void) {return GetParentInst()->GetRemoteRetryMinutes();}
BOOL MakeATQConnection(
SMTPDNS_RECS * pDnsRec,
SOCKET socket,
DWORD IpAddress,
ISMTPConnection *pISMTPConnection,
DWORD Options,
LPSTR pszSSLVerificationName,
DNS_RESOLVER_RECORD *pDNS_RESOLVER_RECORD);
void HandleFailedConnection (ISMTPConnection *pISMTPConnection,
DWORD dwConnectionStatus = CONNECTION_STATUS_FAILED,
DWORD dwConnectedIPAddress = 0);
//
// Used by HandleFailedConnection to report IP address to AQ
//
void ReportConnectedIPAddress(ISMTPConnection *pISMTPConnection,
DWORD dwConnectedIPAddress);
BOOL StartAsyncConnect(const char * HostName,
ISMTPConnection *pISMTPConnection,
DWORD DomainOptions,
BOOL fUseSmartHostAfterFail);
BOOL ConnectToNextResolverHost( CAsyncMx * pThisQ );
BOOL CopyMailToDropDir(ISMTPConnection *pISMTPConnection, const char * DropDirectory);
HANDLE CreateDropFile(const char * DropDir, char * szDropFile);
BOOL ReStartAsyncConnections(
SMTPDNS_RECS * pDnsRecs,
ISMTPConnection * pISMTPConnection,
DWORD DomainParams,
LPSTR pszSSLVerificationName,
DNS_RESOLVER_RECORD *pDNS_RESOLVER_RECORD);
private:
BOOL ConnectToResolverHost( const char * HostName,
LPSTR MyFQDNName,
ISMTPConnection *pISMTPConnection,
DWORD DomainOptions,
BOOL fUseSmartHostAfterFail,
DNS_RESOLVER_RECORD *pDNS_RESOLVER_RECORD,
PSMTPDNS_RECS pDnsRetryRec);
BOOL BeginInitializeAsyncDnsQuery( LPSTR pszHostName,
LPSTR pszFQDN,
ISMTPConnection *pISMTPConnection,
DWORD dwDnsFlags,
DWORD DomainOptions,
BOOL fUseSmartHostAfterFail,
DNS_RESOLVER_RECORD *pDNS_RESOLVER_RECORD,
const char * pszSSLVerificationName,
PSMTPDNS_RECS pRetryDnsRec);
BOOL BeginInitializeAsyncConnect( PSMTPDNS_RECS pDnsRec,
ISMTPConnection *pISMTPConnection,
DWORD DomainOptions,
DNS_RESOLVER_RECORD *pDNS_RESOLVER_RECORD,
const char * pszSSLVerificationName );
BOOL CheckIfAllRcptsHandled( IMailMsgRecipients *pIMsgRecips, DWORD *RcptIndexList, DWORD NumRcpts );
HRESULT SetAllRcptsHandled( IMailMsgRecipients *pIMsgRecips, DWORD *RcptIndexList, DWORD NumRcpts );
};
VOID InternetCompletion(PVOID pvContext, DWORD cbWritten,
DWORD dwCompletionStatus, OVERLAPPED * lpo);
BOOL DnsQueryAsync(
SMTP_SERVER_INSTANCE *pServiceInstance,
LPSTR pszHostName,
LPSTR pszFQDN,
ISMTPConnection *pISMTPConnection,
DWORD dwDnsFlags,
DWORD DomainOptions,
BOOL fUseSmartHostAfterFail,
DNS_RESOLVER_RECORD *pDNS_RESOLVER_RECORD,
const char * pszSSLVerificationName,
RETRYPARAMS *pRetryParams,
BOOL fUdp);
//
// This function has been added to try catch X5 189572 where a NULL
// ISMTPConnection causes us to crash in SMTP_CONNOUT::StartSession.
// Unfortunately by then it is to late to figure out the cause of the
// crash, so this code has been added in strategic places to cause a
// crash at a point where we can diagnose the problem. Note that if
// pISMTPConnection is NULL, we will ALWAYS crash, so this code does
// not make the problem worse, it merely makes it occur earlier
// during the outbound code-path at a point where it can be diagnosed.
//
// -- GPulla
//
inline void CrashOnInvalidSMTPConn(ISMTPConnection *pISMTPConnection)
{
int *p = NULL;
if(g_fCrashOnInvalidSMTPConn && !pISMTPConnection)
*p = 0;
}
#endif