/*++ 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 /************************************************************ * 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