243 lines
8.6 KiB
C++
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
|