public void UpdatePoisonNdrSentToTrue(SubmissionPoisonContext submissionPoisonContext) { this.resourceProtector.EnterReadLock(); try { if (!this.loaded) { return; } ArgumentValidator.ThrowIfNull("submissionPoisonContext", submissionPoisonContext); ArgumentValidator.ThrowIfEmpty("submissionPoisonContext.ResourceGuid", submissionPoisonContext.ResourceGuid); } finally { this.resourceProtector.ExitReadLock(); } this.resourceProtector.EnterWriteLock(); try { if (this.submissionPoisonDataStore.ContainsKey(submissionPoisonContext.ResourceGuid) && this.submissionPoisonDataStore[submissionPoisonContext.ResourceGuid].ContainsKey(submissionPoisonContext.MapiEventCounter)) { ResourceEventCounterCrashInfo resourceEventCounterCrashInfo = this.submissionPoisonDataStore[submissionPoisonContext.ResourceGuid][submissionPoisonContext.MapiEventCounter]; resourceEventCounterCrashInfo.IsPoisonNdrSent = true; this.crashRepository.PersistCrashInfo(submissionPoisonContext.ResourceGuid, submissionPoisonContext.MapiEventCounter, resourceEventCounterCrashInfo, this.maxPoisonEntries); } } finally { this.resourceProtector.ExitWriteLock(); } }
public bool VerifyPoisonMessage(SubmissionPoisonContext submissionPoisonContext) { int num = 0; this.resourceProtector.EnterReadLock(); try { if (!this.loaded) { return(false); } ArgumentValidator.ThrowIfNull("submissionPoisonContext", submissionPoisonContext); ArgumentValidator.ThrowIfEmpty("submissionPoisonContext.ResourceGuid", submissionPoisonContext.ResourceGuid); if (this.submissionPoisonDataStore.ContainsKey(submissionPoisonContext.ResourceGuid) && this.submissionPoisonDataStore[submissionPoisonContext.ResourceGuid].ContainsKey(submissionPoisonContext.MapiEventCounter)) { foreach (DateTime dateTime in this.submissionPoisonDataStore[submissionPoisonContext.ResourceGuid][submissionPoisonContext.MapiEventCounter].CrashTimes) { if (!StoreDriverUtils.CheckIfDateTimeExceedsThreshold(dateTime, DateTime.UtcNow, this.poisonEntryExpiryWindow)) { num++; } } if (num >= this.PoisonThreshold) { return(true); } } } finally { this.resourceProtector.ExitReadLock(); } return(false); }
private void LogPoisonMessageMTL(SubmissionInfo submissionInfo, SubmissionPoisonContext submissionPoisonContext) { this.storeDriverTracer.StoreDriverSubmissionTracer.TracePass <SubmissionInfo>(this.storeDriverTracer.MessageProbeActivityId, 0L, "Found poison message for {0}", submissionInfo); MsgTrackPoisonInfo msgTrackingPoisonInfo = new MsgTrackPoisonInfo(submissionInfo.NetworkAddress, submissionInfo.MailboxFqdn, StoreDriverSubmission.LocalIPAddress, submissionPoisonContext.MapiEventCounter.ToString() + ": " + submissionPoisonContext.ResourceGuid.ToString()); MessageTrackingLog.TrackPoisonMessage(MessageTrackingSource.STOREDRIVER, msgTrackingPoisonInfo); submissionInfo.LogEvent(SubmissionInfo.Event.StoreDriverSubmissionPoisonMessageInSubmission); }
public void SavePoisonContext(SubmissionPoisonContext submissionPoisonContext) { this.resourceProtector.EnterReadLock(); try { if (!this.loaded) { return; } if (submissionPoisonContext == null || submissionPoisonContext.ResourceGuid == Guid.Empty) { this.storeDriverTracer.GeneralTracer.TracePass(this.storeDriverTracer.MessageProbeActivityId, 0L, "Poison context information cannot be store on the crashing thread. Exiting..."); return; } } finally { this.resourceProtector.ExitReadLock(); } this.resourceProtector.EnterWriteLock(); try { ResourceEventCounterCrashInfo resourceEventCounterCrashInfo; if (this.submissionPoisonDataStore.ContainsKey(submissionPoisonContext.ResourceGuid) && this.submissionPoisonDataStore[submissionPoisonContext.ResourceGuid].ContainsKey(submissionPoisonContext.MapiEventCounter)) { resourceEventCounterCrashInfo = this.submissionPoisonDataStore[submissionPoisonContext.ResourceGuid][submissionPoisonContext.MapiEventCounter]; } else { resourceEventCounterCrashInfo = new ResourceEventCounterCrashInfo(new SortedSet <DateTime>(), false); } resourceEventCounterCrashInfo.CrashTimes.Add(DateTime.UtcNow); try { this.crashRepository.PersistCrashInfo(submissionPoisonContext.ResourceGuid, submissionPoisonContext.MapiEventCounter, resourceEventCounterCrashInfo, this.maxPoisonEntries); } catch (CrashRepositoryAccessException) { } } finally { this.resourceProtector.ExitWriteLock(); } }
public bool VerifyPoisonNdrSent(SubmissionPoisonContext submissionPoisonContext) { this.resourceProtector.EnterReadLock(); try { if (!this.loaded) { return(false); } ArgumentValidator.ThrowIfNull("submissionPoisonContext", submissionPoisonContext); ArgumentValidator.ThrowIfEmpty("submissionPoisonContext.ResourceGuid", submissionPoisonContext.ResourceGuid); if (this.submissionPoisonDataStore.ContainsKey(submissionPoisonContext.ResourceGuid) && this.submissionPoisonDataStore[submissionPoisonContext.ResourceGuid].ContainsKey(submissionPoisonContext.MapiEventCounter)) { return(this.submissionPoisonDataStore[submissionPoisonContext.ResourceGuid][submissionPoisonContext.MapiEventCounter].IsPoisonNdrSent); } } finally { this.resourceProtector.ExitReadLock(); } return(false); }
private MailSubmissionResult SubmitMessageImpl(MapiSubmissionInfo submissionInfo, SubmissionPoisonHandler submissionPoisonHandler, QuarantineHandler quarantineHandler) { MailSubmissionResult mailSubmissionResult = new MailSubmissionResult(); if (this.Retired) { mailSubmissionResult.ErrorCode = 2214592514U; return(mailSubmissionResult); } string mailboxFqdn = submissionInfo.MailboxFqdn; string database = submissionInfo.MdbGuid.ToString(); MailSubmissionResult result; using (submissionInfo.GetTraceFilter()) { using (SubmissionConnectionWrapper connection = SubmissionConnectionPool.GetConnection(mailboxFqdn, database)) { using (SubmissionThreadLimiter submissionThreadLimiter = new SubmissionThreadLimiter()) { SubmissionPoisonContext submissionPoisonContext = null; try { submissionThreadLimiter.BeginSubmission(connection.Id, mailboxFqdn, database); if (this.Retired) { mailSubmissionResult.ErrorCode = 2214592514U; connection.SubmissionAborted("Retiring."); result = mailSubmissionResult; } else { this.storeDriverTracer.StoreDriverSubmissionTracer.TracePfdPass <int, MapiSubmissionInfo>(this.storeDriverTracer.MessageProbeActivityId, 0L, "PFD ESD {0} Processing SubmitMessage for {1}", 27547, submissionInfo); submissionPoisonContext = submissionInfo.GetPoisonContext(); MailItemSubmitter mailItemSubmitter2; MailItemSubmitter mailItemSubmitter = mailItemSubmitter2 = new MailItemSubmitter(connection.Id, submissionInfo, this.sendAsManager, submissionPoisonHandler, submissionPoisonContext, this); try { QuarantineInfoContext quarantineInfoContext; TimeSpan timeSpan; if (SubmissionConfiguration.Instance.App.EnableMailboxQuarantine && quarantineHandler.IsResourceQuarantined(submissionPoisonContext.ResourceGuid, out quarantineInfoContext, out timeSpan)) { mailSubmissionResult.ErrorCode = 1140850696U; mailSubmissionResult.QuarantineTimeSpan = timeSpan; mailSubmissionResult.DiagnosticInfo = string.Format("{0}:{1}, QuarantineRemainingTimeSpan:{2}", "QuarantineStart", quarantineInfoContext.QuarantineStartTime, timeSpan); connection.SubmissionFailed(string.Format("Resource {0} is in quarantined state", submissionPoisonContext.ResourceGuid)); return(mailSubmissionResult); } if (this.PoisonMessageDectionEnabled && submissionPoisonHandler.VerifyPoisonMessage(submissionPoisonContext)) { this.LogPoisonMessageMTL(submissionInfo, submissionPoisonContext); if (SubmissionConfiguration.Instance.App.EnableSendNdrForPoisonMessage) { if (!submissionPoisonHandler.VerifyPoisonNdrSent(submissionPoisonContext)) { mailItemSubmitter.HandlePoisonMessageNdrSubmission(); mailSubmissionResult.ErrorCode = StoreDriverSubmissionUtils.MapSubmissionStatusErrorCodeToPoisonErrorCode(mailItemSubmitter.Result.ErrorCode); } } else { mailSubmissionResult.ErrorCode = 3U; } connection.SubmissionAborted(string.Format("Poison Context Info: Resource = {0};EventCounter = {1}.", submissionPoisonContext.ResourceGuid, submissionPoisonContext.MapiEventCounter)); return(mailSubmissionResult); } Thread currentThread = Thread.CurrentThread; try { this.SubmissionsInProgress[currentThread] = mailItemSubmitter; mailItemSubmitter.Submit(); mailSubmissionResult.RemoteHostName = mailItemSubmitter.Result.RemoteHostName; } finally { this.SubmissionsInProgress.Remove(currentThread); } } finally { if (mailItemSubmitter2 != null) { ((IDisposable)mailItemSubmitter2).Dispose(); } } if (mailItemSubmitter.Result.ErrorCode == 0U) { connection.SubmissionSuccessful(mailItemSubmitter.MessageSize, mailItemSubmitter.RecipientCount); } else { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("HResult: "); stringBuilder.Append(mailItemSubmitter.Result.ErrorCode.ToString()); stringBuilder.Append("; DiagnosticInfo: "); stringBuilder.Append(mailItemSubmitter.Result.DiagnosticInfo); connection.SubmissionFailed(stringBuilder.ToString()); } if (mailItemSubmitter.Result.ErrorCode == 3U) { submissionInfo.LogEvent(SubmissionInfo.Event.StoreDriverSubmissionPoisonMessageInSubmission); } result = mailItemSubmitter.Result; } } catch (ThreadLimitExceededException ex) { connection.SubmissionAborted(ex.Message); mailSubmissionResult.ErrorCode = 1090519042U; mailSubmissionResult.DiagnosticInfo = ex.Message; result = mailSubmissionResult; } catch (Exception exception) { try { submissionPoisonHandler.SavePoisonContext(submissionPoisonContext); string exceptionDiagnosticInfo = StorageExceptionHandler.GetExceptionDiagnosticInfo(exception); connection.SubmissionFailed("Exception: " + exceptionDiagnosticInfo); submissionInfo.LogEvent(SubmissionInfo.Event.StoreDriverSubmissionPoisonMessage, exception); FailFast.Fail(exception); } catch (Exception ex2) { StoreDriverSubmission.LogEvent(MSExchangeStoreDriverSubmissionEventLogConstants.Tuple_StoreDriverSubmissionFailFastFailure, null, new object[] { ex2 }); } result = mailSubmissionResult; } } } } return(result); }