public static WsrmFault ValidateTerminateSequenceResponse(ChannelReliableSession session, UniqueId messageId, WsrmMessageInfo info, long last) { string exceptionMessage = null; string faultReason = null; if (info.WsrmHeaderFault is UnknownSequenceFault) { return(null); } if (info.TerminateSequenceResponseInfo == null) { exceptionMessage = System.ServiceModel.SR.GetString("InvalidWsrmResponseSessionFaultedExceptionString", new object[] { "TerminateSequence", info.Action, "http://docs.oasis-open.org/ws-rx/wsrm/200702/TerminateSequenceResponse" }); faultReason = System.ServiceModel.SR.GetString("InvalidWsrmResponseSessionFaultedFaultString", new object[] { "TerminateSequence", info.Action, "http://docs.oasis-open.org/ws-rx/wsrm/200702/TerminateSequenceResponse" }); } else if (!object.Equals(messageId, info.TerminateSequenceResponseInfo.RelatesTo)) { exceptionMessage = System.ServiceModel.SR.GetString("WsrmMessageWithWrongRelatesToExceptionString", new object[] { "TerminateSequence" }); faultReason = System.ServiceModel.SR.GetString("WsrmMessageWithWrongRelatesToFaultString", new object[] { "TerminateSequence" }); } else { return(ValidateFinalAck(session, info, last)); } return(SequenceTerminatedFault.CreateProtocolFault(session.OutputID, faultReason, exceptionMessage)); }
void OnInactivityElapsed(object state) { WsrmFault fault; Exception e; string exceptionMessage = SR.GetString(SR.SequenceTerminatedInactivityTimeoutExceeded, this.settings.InactivityTimeout); if (TD.InactivityTimeoutIsEnabled()) { TD.InactivityTimeout(exceptionMessage); } if (this.SequenceID != null) { string faultReason = SR.GetString(SR.SequenceTerminatedInactivityTimeoutExceeded, this.settings.InactivityTimeout); fault = SequenceTerminatedFault.CreateCommunicationFault(this.SequenceID, faultReason, exceptionMessage); e = fault.CreateException(); } else { fault = null; e = new CommunicationException(exceptionMessage); } OnLocalFault(e, fault, null); }
protected override WsrmFault ProcessRequestorResponse(ReliableRequestor requestor, string requestName, WsrmMessageInfo info) { string faultReason = System.ServiceModel.SR.GetString("ReceivedResponseBeforeRequestFaultString", new object[] { requestName }); string exceptionMessage = System.ServiceModel.SR.GetString("ReceivedResponseBeforeRequestExceptionString", new object[] { requestName }); return(SequenceTerminatedFault.CreateProtocolFault(base.ReliableSession.OutputID, faultReason, exceptionMessage)); }
bool InternalAddMessage(Message message, TimeSpan timeout, object state, bool isLast) { MessageAttemptInfo attemptInfo; TimeoutHelper helper = new TimeoutHelper(timeout); try { if (isLast) { if (state != null) { throw Fx.AssertAndThrow("The isLast overload does not take a state."); } attemptInfo = this.strategy.AddLast(message, helper.RemainingTime(), null); } else if (!this.strategy.Add(message, helper.RemainingTime(), state, out attemptInfo)) { return(false); } } catch (TimeoutException) { if (isLast) { this.RaiseFault(null, SequenceTerminatedFault.CreateCommunicationFault(this.id, SR.GetString(SR.SequenceTerminatedAddLastToWindowTimedOut), null)); } // else - RM does not fault the channel based on a timeout exception trying to add a sequenced message to the window. throw; } catch (Exception e) { if (!Fx.IsFatal(e)) { this.RaiseFault(null, SequenceTerminatedFault.CreateCommunicationFault(this.id, SR.GetString(SR.SequenceTerminatedUnknownAddToWindowError), null)); } throw; } if (sendGuard.Enter()) { try { this.sendHandler(attemptInfo, helper.RemainingTime(), false); } catch (QuotaExceededException) { this.RaiseFault(null, SequenceTerminatedFault.CreateQuotaExceededFault(this.id)); throw; } finally { this.sendGuard.Exit(); } } return(true); }
protected override WsrmFault ProcessRequestorResponse(ReliableRequestor requestor, string requestName, WsrmMessageInfo info) { string faultString = SR.Format(SR.ReceivedResponseBeforeRequestFaultString, requestName); string exceptionString = SR.Format(SR.ReceivedResponseBeforeRequestExceptionString, requestName); return(SequenceTerminatedFault.CreateProtocolFault(ReliableSession.OutputID, faultString, exceptionString)); }
protected override WsrmFault VerifySimplexProtocolElements(WsrmMessageInfo info) { if ((info.AcknowledgementInfo != null) && (info.AcknowledgementInfo.SequenceID != base.OutputID)) { return(new UnknownSequenceFault(info.AcknowledgementInfo.SequenceID)); } if (info.AckRequestedInfo != null) { return(SequenceTerminatedFault.CreateProtocolFault(base.OutputID, System.ServiceModel.SR.GetString("SequenceTerminatedUnexpectedAckRequested"), System.ServiceModel.SR.GetString("UnexpectedAckRequested"))); } if (info.CreateSequenceInfo != null) { return(SequenceTerminatedFault.CreateProtocolFault(base.OutputID, System.ServiceModel.SR.GetString("SequenceTerminatedUnexpectedCS"), System.ServiceModel.SR.GetString("UnexpectedCS"))); } if (info.SequencedMessageInfo != null) { return(new UnknownSequenceFault(info.SequencedMessageInfo.SequenceID)); } if (info.TerminateSequenceInfo != null) { if (base.Settings.ReliableMessagingVersion == ReliableMessagingVersion.WSReliableMessagingFebruary2005) { return(SequenceTerminatedFault.CreateProtocolFault(base.OutputID, System.ServiceModel.SR.GetString("SequenceTerminatedUnexpectedTerminateSequence"), System.ServiceModel.SR.GetString("UnexpectedTerminateSequence"))); } if (info.TerminateSequenceInfo.Identifier == base.OutputID) { return(null); } return(new UnknownSequenceFault(info.TerminateSequenceInfo.Identifier)); } if (info.TerminateSequenceResponseInfo != null) { WsrmUtilities.AssertWsrm11(base.Settings.ReliableMessagingVersion); if (info.TerminateSequenceResponseInfo.Identifier == base.OutputID) { return(null); } return(new UnknownSequenceFault(info.TerminateSequenceResponseInfo.Identifier)); } if (info.CloseSequenceInfo != null) { WsrmUtilities.AssertWsrm11(base.Settings.ReliableMessagingVersion); if (info.CloseSequenceInfo.Identifier == base.OutputID) { return(SequenceTerminatedFault.CreateProtocolFault(base.OutputID, System.ServiceModel.SR.GetString("SequenceTerminatedUnsupportedClose"), System.ServiceModel.SR.GetString("UnsupportedCloseExceptionString"))); } return(new UnknownSequenceFault(info.CloseSequenceInfo.Identifier)); } if (info.CloseSequenceResponseInfo == null) { return(null); } WsrmUtilities.AssertWsrm11(base.Settings.ReliableMessagingVersion); if (info.CloseSequenceResponseInfo.Identifier == base.OutputID) { return(null); } return(new UnknownSequenceFault(info.CloseSequenceResponseInfo.Identifier)); }
public virtual void Abort() { this.guard.Abort(); this.inactivityTimer.Abort(); // Try to send a fault. bool sendFault; lock (this.ThisLock) { // Faulted thread already cleaned up. No need to to anything more. if (this.faulted == SessionFaultState.CleanedUp) { return; } // Can only send a fault if the other side did not send one already. sendFault = this.canSendFault && (this.faulted != SessionFaultState.RemotelyFaulted); // NotFaulted || LocallyFaulted this.faulted = SessionFaultState.CleanedUp; } if (sendFault) { if ((this.binder.State == CommunicationState.Opened) && this.binder.Connected && (this.binder.CanSendAsynchronously || (this.replyFaultContext != null))) { if (this.terminatingFault == null) { UniqueId sequenceId = this.InputID ?? this.OutputID; if (sequenceId != null) { WsrmFault fault = SequenceTerminatedFault.CreateCommunicationFault(sequenceId, SR.GetString(SR.SequenceTerminatedOnAbort), null); this.terminatingFault = fault.CreateMessage(this.settings.MessageVersion, this.settings.ReliableMessagingVersion); } } if (this.terminatingFault != null) { this.AddFinalRanges(); this.faultHelper.SendFaultAsync(this.binder, this.replyFaultContext, this.terminatingFault); return; } } } // Got here so the session did not actually send a fault, must clean up resources. if (this.terminatingFault != null) { this.terminatingFault.Close(); } if (this.replyFaultContext != null) { this.replyFaultContext.Abort(); } this.binder.Abort(); }
public AddAsyncResult(Message message, bool isLast, TimeSpan timeout, object state, ReliableOutputConnection connection, AsyncCallback callback, object asyncState) : base(callback, asyncState) { this.connection = connection; this.timeoutHelper = new TimeoutHelper(timeout); this.isLast = isLast; bool complete = false; IAsyncResult result; try { if (isLast) { if (state != null) { throw Fx.AssertAndThrow("The isLast overload does not take a state."); } result = this.connection.strategy.BeginAddLast(message, this.timeoutHelper.RemainingTime(), state, addCompleteStatic, this); } else { result = this.connection.strategy.BeginAdd(message, this.timeoutHelper.RemainingTime(), state, addCompleteStatic, this); } } catch (TimeoutException) { if (isLast) { this.connection.RaiseFault(null, SequenceTerminatedFault.CreateCommunicationFault(this.connection.id, SR.GetString(SR.SequenceTerminatedAddLastToWindowTimedOut), null)); } // else - RM does not fault the channel based on a timeout exception trying to add a sequenced message to the window. throw; } catch (Exception e) { if (!Fx.IsFatal(e)) { this.connection.RaiseFault(null, SequenceTerminatedFault.CreateCommunicationFault(this.connection.id, SR.GetString(SR.SequenceTerminatedUnknownAddToWindowError), null)); } throw; } if (result.CompletedSynchronously) { complete = this.CompleteAdd(result); } if (complete) { this.Complete(true); } }
void OnConnectionSend(MessageAttemptInfo attemptInfo, TimeSpan timeout, bool maskUnhandledException) { using (attemptInfo.Message) { if (attemptInfo.RetryCount > this.settings.MaxRetryCount) { if (TD.MaxRetryCyclesExceededIsEnabled()) { TD.MaxRetryCyclesExceeded(SR.GetString(SR.MaximumRetryCountExceeded)); } this.session.OnLocalFault(new CommunicationException(SR.GetString(SR.MaximumRetryCountExceeded), this.maxRetryCountException), SequenceTerminatedFault.CreateMaxRetryCountExceededFault(this.session.OutputID), null); return; } this.AddAcknowledgementHeader(attemptInfo.Message, false); this.session.OnLocalActivity(); Message reply = null; MaskingMode maskingMode = maskUnhandledException ? MaskingMode.Unhandled : MaskingMode.None; if (attemptInfo.RetryCount < this.settings.MaxRetryCount) { maskingMode |= MaskingMode.Handled; reply = this.binder.Request(attemptInfo.Message, timeout, maskingMode); } else { try { reply = this.binder.Request(attemptInfo.Message, timeout, maskingMode); } catch (Exception e) { if (Fx.IsFatal(e)) { throw; } if (this.binder.IsHandleable(e)) { this.maxRetryCountException = e; } else { throw; } } } if (reply != null) { ProcessReply(reply, (IReliableRequest)attemptInfo.State, attemptInfo.GetSequenceNumber()); } } }
private async Task OnConnectionSendAsync(MessageAttemptInfo attemptInfo, TimeSpan timeout, bool maskUnhandledException) { using (attemptInfo.Message) { if (attemptInfo.RetryCount > settings.MaxRetryCount) { if (WcfEventSource.Instance.MaxRetryCyclesExceededIsEnabled()) { WcfEventSource.Instance.MaxRetryCyclesExceeded(SR.MaximumRetryCountExceeded); } session.OnLocalFault(new CommunicationException(SR.MaximumRetryCountExceeded, maxRetryCountException), SequenceTerminatedFault.CreateMaxRetryCountExceededFault(session.OutputID), null); return; } AddAcknowledgementHeader(attemptInfo.Message, false); session.OnLocalActivity(); Message reply = null; MaskingMode maskingMode = maskUnhandledException ? MaskingMode.Unhandled : MaskingMode.None; if (attemptInfo.RetryCount < settings.MaxRetryCount) { maskingMode |= MaskingMode.Handled; reply = await binder.RequestAsync(attemptInfo.Message, timeout, maskingMode); } else { try { reply = await binder.RequestAsync(attemptInfo.Message, timeout, maskingMode); } catch (Exception e) { if (Fx.IsFatal(e)) { throw; } if (binder.IsHandleable(e)) { maxRetryCountException = e; } else { throw; } } } if (reply != null) { ProcessReply(reply, (IReliableRequest)attemptInfo.State, attemptInfo.GetSequenceNumber()); } } }
public static WsrmFault ValidateFinalAckExists(ChannelReliableSession session, WsrmAcknowledgmentInfo ackInfo) { if ((ackInfo != null) && ackInfo.Final) { return(null); } string exceptionMessage = System.ServiceModel.SR.GetString("MissingFinalAckExceptionString"); string faultReason = System.ServiceModel.SR.GetString("SequenceTerminatedMissingFinalAck"); return(SequenceTerminatedFault.CreateProtocolFault(session.OutputID, faultReason, exceptionMessage)); }
private bool InternalAddMessage(Message message, TimeSpan timeout, object state, bool isLast) { MessageAttemptInfo info; TimeoutHelper helper = new TimeoutHelper(timeout); try { if (isLast) { if (state != null) { throw Fx.AssertAndThrow("The isLast overload does not take a state."); } info = this.strategy.AddLast(message, helper.RemainingTime(), null); } else if (!this.strategy.Add(message, helper.RemainingTime(), state, out info)) { return(false); } } catch (TimeoutException) { if (isLast) { this.RaiseFault(null, SequenceTerminatedFault.CreateCommunicationFault(this.id, System.ServiceModel.SR.GetString("SequenceTerminatedAddLastToWindowTimedOut"), null)); } throw; } catch (Exception exception) { if (!Fx.IsFatal(exception)) { this.RaiseFault(null, SequenceTerminatedFault.CreateCommunicationFault(this.id, System.ServiceModel.SR.GetString("SequenceTerminatedUnknownAddToWindowError"), null)); } throw; } if (this.sendGuard.Enter()) { try { this.sendHandler(info, helper.RemainingTime(), false); } catch (QuotaExceededException) { this.RaiseFault(null, SequenceTerminatedFault.CreateQuotaExceededFault(this.id)); throw; } finally { this.sendGuard.Exit(); } } return(true); }
private void OnBinderException(IReliableChannelBinder sender, Exception exception) { if (exception is QuotaExceededException) { this.session.OnLocalFault(exception, SequenceTerminatedFault.CreateQuotaExceededFault(this.session.OutputID), null); } else { base.EnqueueAndDispatch(exception, null, false); } }
protected override WsrmFault ProcessRequestorResponse(ReliableRequestor requestor, string requestName, WsrmMessageInfo info) { if (requestor != null) { requestor.SetInfo(info); return(null); } else { string faultString = SR.GetString(SR.ReceivedResponseBeforeRequestFaultString, requestName); string exceptionString = SR.GetString(SR.ReceivedResponseBeforeRequestExceptionString, requestName); return(SequenceTerminatedFault.CreateProtocolFault(this.ReliableSession.OutputID, faultString, exceptionString)); } }
private void OnBinderException(IReliableChannelBinder sender, Exception exception) { if (exception is QuotaExceededException) { if (((base.State == CommunicationState.Opening) || (base.State == CommunicationState.Opened)) || (base.State == CommunicationState.Closing)) { this.session.OnLocalFault(exception, SequenceTerminatedFault.CreateQuotaExceededFault(this.session.OutputID), null); } } else { base.AddPendingException(exception); } }
public AddAsyncResult(Message message, bool isLast, TimeSpan timeout, object state, ReliableOutputConnection connection, AsyncCallback callback, object asyncState) : base(callback, asyncState) { IAsyncResult result; this.connection = connection; this.timeoutHelper = new TimeoutHelper(timeout); this.isLast = isLast; bool flag = false; try { if (isLast) { if (state != null) { throw Fx.AssertAndThrow("The isLast overload does not take a state."); } result = this.connection.strategy.BeginAddLast(message, this.timeoutHelper.RemainingTime(), state, addCompleteStatic, this); } else { result = this.connection.strategy.BeginAdd(message, this.timeoutHelper.RemainingTime(), state, addCompleteStatic, this); } } catch (TimeoutException) { if (isLast) { this.connection.RaiseFault(null, SequenceTerminatedFault.CreateCommunicationFault(this.connection.id, System.ServiceModel.SR.GetString("SequenceTerminatedAddLastToWindowTimedOut"), null)); } throw; } catch (Exception exception) { if (!Fx.IsFatal(exception)) { this.connection.RaiseFault(null, SequenceTerminatedFault.CreateCommunicationFault(this.connection.id, System.ServiceModel.SR.GetString("SequenceTerminatedUnknownAddToWindowError"), null)); } throw; } if (result.CompletedSynchronously) { flag = this.CompleteAdd(result); } if (flag) { base.Complete(true); } }
private void CompleteSend(IAsyncResult result) { try { this.connection.endSendHandler(result); } catch (QuotaExceededException) { this.connection.RaiseFault(null, SequenceTerminatedFault.CreateQuotaExceededFault(this.connection.id)); throw; } finally { this.connection.sendGuard.Exit(); } }
public static bool ValidateWsrmRequest(ChannelReliableSession session, WsrmRequestInfo info, IReliableChannelBinder binder, RequestContext context) { if (!(info is CloseSequenceInfo) && !(info is TerminateSequenceInfo)) { throw Fx.AssertAndThrow("Method is meant for CloseSequence or TerminateSequence only."); } if (info.ReplyTo.Uri != binder.RemoteAddress.Uri) { string faultReason = System.ServiceModel.SR.GetString("WsrmRequestIncorrectReplyToFaultString", new object[] { info.RequestName }); string exceptionMessage = System.ServiceModel.SR.GetString("WsrmRequestIncorrectReplyToExceptionString", new object[] { info.RequestName }); WsrmFault fault = SequenceTerminatedFault.CreateProtocolFault(session.InputID, faultReason, exceptionMessage); session.OnLocalFault(fault.CreateException(), fault, context); return(false); } return(true); }
IAsyncResult OnConnectionBeginSendHandler(MessageAttemptInfo attemptInfo, TimeSpan timeout, bool maskUnhandledException, AsyncCallback callback, object state) { if (attemptInfo.RetryCount > this.settings.MaxRetryCount) { if (TD.MaxRetryCyclesExceededIsEnabled()) { TD.MaxRetryCyclesExceeded(SR.GetString(SR.MaximumRetryCountExceeded)); } this.session.OnLocalFault(new CommunicationException(SR.GetString(SR.MaximumRetryCountExceeded), this.maxRetryCountException), SequenceTerminatedFault.CreateMaxRetryCountExceededFault(this.session.OutputID), null); return(new CompletedAsyncResult(callback, state)); } else { this.session.OnLocalActivity(); return(this.OnConnectionBeginSend(attemptInfo, timeout, maskUnhandledException, callback, state)); } }
protected override WsrmFault VerifyDuplexProtocolElements(WsrmMessageInfo info) { WsrmFault fault = base.VerifyDuplexProtocolElements(info); if (fault != null) { return(fault); } if ((info.CreateSequenceInfo != null) && (info.CreateSequenceInfo.OfferIdentifier != base.OutputID)) { return(SequenceTerminatedFault.CreateProtocolFault(base.OutputID, System.ServiceModel.SR.GetString("SequenceTerminatedUnexpectedCSOfferId"), System.ServiceModel.SR.GetString("UnexpectedCSOfferId"))); } if (info.CreateSequenceResponseInfo != null) { return(SequenceTerminatedFault.CreateProtocolFault(base.OutputID, System.ServiceModel.SR.GetString("SequenceTerminatedUnexpectedCSR"), System.ServiceModel.SR.GetString("UnexpectedCSR"))); } return(null); }
private void OnInactivityElapsed(object state) { WsrmFault fault; Exception exception; string exceptionMessage = System.ServiceModel.SR.GetString("SequenceTerminatedInactivityTimeoutExceeded", new object[] { this.settings.InactivityTimeout }); if (this.SequenceID != null) { string faultReason = System.ServiceModel.SR.GetString("SequenceTerminatedInactivityTimeoutExceeded", new object[] { this.settings.InactivityTimeout }); fault = SequenceTerminatedFault.CreateCommunicationFault(this.SequenceID, faultReason, exceptionMessage); exception = fault.CreateException(); } else { fault = null; exception = new CommunicationException(exceptionMessage); } this.OnLocalFault(exception, fault, null); }
public virtual void Abort() { bool flag; this.guard.Abort(); this.inactivityTimer.Abort(); lock (this.ThisLock) { if (this.faulted == SessionFaultState.CleanedUp) { return; } flag = this.canSendFault && (this.faulted != SessionFaultState.RemotelyFaulted); this.faulted = SessionFaultState.CleanedUp; } if (((flag && (this.binder.State == CommunicationState.Opened)) && this.binder.Connected) && (this.binder.CanSendAsynchronously || (this.replyFaultContext != null))) { if (this.terminatingFault == null) { UniqueId sequenceID = this.InputID ?? this.OutputID; if (sequenceID != null) { this.terminatingFault = SequenceTerminatedFault.CreateCommunicationFault(sequenceID, System.ServiceModel.SR.GetString("SequenceTerminatedOnAbort"), null).CreateMessage(this.settings.MessageVersion, this.settings.ReliableMessagingVersion); } } if (this.terminatingFault != null) { this.AddFinalRanges(); this.faultHelper.SendFaultAsync(this.binder, this.replyFaultContext, this.terminatingFault); return; } } if (this.terminatingFault != null) { this.terminatingFault.Close(); } if (this.replyFaultContext != null) { this.replyFaultContext.Abort(); } this.binder.Abort(); }
private async Task OnConnectionSendAsyncHandler(MessageAttemptInfo attemptInfo, TimeSpan timeout, bool maskUnhandledException) { using (attemptInfo.Message) { if (attemptInfo.RetryCount > Settings.MaxRetryCount) { if (WcfEventSource.Instance.MaxRetryCyclesExceededIsEnabled()) { WcfEventSource.Instance.MaxRetryCyclesExceeded(SR.MaximumRetryCountExceeded); } _session.OnLocalFault(new CommunicationException(SR.MaximumRetryCountExceeded, _maxRetryCountException), SequenceTerminatedFault.CreateMaxRetryCountExceededFault(_session.OutputID), null); } else { _session.OnLocalActivity(); await OnConnectionSendAsync(attemptInfo.Message, timeout, (attemptInfo.RetryCount == Settings.MaxRetryCount), maskUnhandledException); } } }
void OnConnectionSendHandler(MessageAttemptInfo attemptInfo, TimeSpan timeout, bool maskUnhandledException) { using (attemptInfo.Message) { if (attemptInfo.RetryCount > this.settings.MaxRetryCount) { if (TD.MaxRetryCyclesExceededIsEnabled()) { TD.MaxRetryCyclesExceeded(SR.GetString(SR.MaximumRetryCountExceeded)); } this.session.OnLocalFault(new CommunicationException(SR.GetString(SR.MaximumRetryCountExceeded), this.maxRetryCountException), SequenceTerminatedFault.CreateMaxRetryCountExceededFault(this.session.OutputID), null); } else { this.session.OnLocalActivity(); OnConnectionSend(attemptInfo.Message, timeout, (attemptInfo.RetryCount == this.settings.MaxRetryCount), maskUnhandledException); } } }
protected override WsrmFault VerifyDuplexProtocolElements(WsrmMessageInfo info) { WsrmFault fault = base.VerifyDuplexProtocolElements(info); if (fault != null) { return(fault); } else if (info.CreateSequenceInfo != null && info.CreateSequenceInfo.OfferIdentifier != this.OutputID) { return(SequenceTerminatedFault.CreateProtocolFault(this.OutputID, SR.GetString(SR.SequenceTerminatedUnexpectedCSOfferId), SR.GetString(SR.UnexpectedCSOfferId))); } else if (info.CreateSequenceResponseInfo != null) { return(SequenceTerminatedFault.CreateProtocolFault(this.OutputID, SR.GetString(SR.SequenceTerminatedUnexpectedCSR), SR.GetString(SR.UnexpectedCSR))); } else { return(null); } }
private void ThrowIfCloseInvalid() { bool flag = false; if (this.listener.ReliableMessagingVersion == ReliableMessagingVersion.WSReliableMessagingFebruary2005) { if ((this.DeliveryStrategy.EnqueuedCount > 0) || (this.Connection.Ranges.Count > 1)) { flag = true; } } else if ((this.listener.ReliableMessagingVersion == ReliableMessagingVersion.WSReliableMessaging11) && (this.DeliveryStrategy.EnqueuedCount > 0)) { flag = true; } if (flag) { WsrmFault fault = SequenceTerminatedFault.CreateProtocolFault(this.session.InputID, System.ServiceModel.SR.GetString("SequenceTerminatedSessionClosedBeforeDone"), System.ServiceModel.SR.GetString("SessionClosedBeforeDone")); this.session.OnLocalFault(null, fault, null); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(fault.CreateException()); } }
IAsyncResult OnConnectionBeginSend(MessageAttemptInfo attemptInfo, TimeSpan timeout, bool maskUnhandledException, AsyncCallback callback, object state) { if (attemptInfo.RetryCount > this.settings.MaxRetryCount) { if (TD.MaxRetryCyclesExceededIsEnabled()) { TD.MaxRetryCyclesExceeded(SR.GetString(SR.MaximumRetryCountExceeded)); } this.session.OnLocalFault(new CommunicationException(SR.GetString(SR.MaximumRetryCountExceeded), this.maxRetryCountException), SequenceTerminatedFault.CreateMaxRetryCountExceededFault(this.session.OutputID), null); return(new CompletedAsyncResult(callback, state)); } else { this.session.OnLocalActivity(); this.AddAcknowledgementHeader(attemptInfo.Message, false); ReliableBinderRequestAsyncResult result = new ReliableBinderRequestAsyncResult(callback, state); result.Binder = this.binder; result.MessageAttemptInfo = attemptInfo; result.MaskingMode = maskUnhandledException ? MaskingMode.Unhandled : MaskingMode.None; if (attemptInfo.RetryCount < this.settings.MaxRetryCount) { result.MaskingMode |= MaskingMode.Handled; result.SaveHandledException = false; } else { result.SaveHandledException = true; } result.Begin(timeout); return(result); } }
void ProcessReply(Message reply, IReliableRequest request, Int64 requestSequenceNumber) { WsrmMessageInfo messageInfo = WsrmMessageInfo.Get(this.settings.MessageVersion, this.settings.ReliableMessagingVersion, this.binder.Channel, this.binder.GetInnerSession(), reply); if (!this.session.ProcessInfo(messageInfo, null)) { return; } if (!this.session.VerifyDuplexProtocolElements(messageInfo, null)) { return; } bool wsrm11 = this.settings.ReliableMessagingVersion == ReliableMessagingVersion.WSReliableMessaging11; if (messageInfo.WsrmHeaderFault != null) { // Close message now, going to stop processing in all cases. messageInfo.Message.Close(); if (!(messageInfo.WsrmHeaderFault is UnknownSequenceFault)) { throw Fx.AssertAndThrow("Fault must be UnknownSequence fault."); } if (this.terminateRequestor == null) { throw Fx.AssertAndThrow("If we start getting UnknownSequence, terminateRequestor cannot be null."); } this.terminateRequestor.SetInfo(messageInfo); return; } if (messageInfo.AcknowledgementInfo == null) { WsrmFault fault = SequenceTerminatedFault.CreateProtocolFault(this.session.InputID, SR.GetString(SR.SequenceTerminatedReplyMissingAcknowledgement), SR.GetString(SR.ReplyMissingAcknowledgement)); messageInfo.Message.Close(); this.session.OnLocalFault(fault.CreateException(), fault, null); return; } if (wsrm11 && (messageInfo.TerminateSequenceInfo != null)) { UniqueId faultId = (messageInfo.TerminateSequenceInfo.Identifier == this.session.OutputID) ? this.session.InputID : this.session.OutputID; WsrmFault fault = SequenceTerminatedFault.CreateProtocolFault(faultId, SR.GetString(SR.SequenceTerminatedUnsupportedTerminateSequence), SR.GetString(SR.UnsupportedTerminateSequenceExceptionString)); messageInfo.Message.Close(); this.session.OnLocalFault(fault.CreateException(), fault, null); return; } else if (wsrm11 && messageInfo.AcknowledgementInfo.Final) { // Close message now, going to stop processing in all cases. messageInfo.Message.Close(); if (this.closeRequestor == null) { // Remote endpoint signaled Close, this is not allowed so we fault. string exceptionString = SR.GetString(SR.UnsupportedCloseExceptionString); string faultString = SR.GetString(SR.SequenceTerminatedUnsupportedClose); WsrmFault fault = SequenceTerminatedFault.CreateProtocolFault(this.session.OutputID, faultString, exceptionString); this.session.OnLocalFault(fault.CreateException(), fault, null); } else { WsrmFault fault = WsrmUtilities.ValidateFinalAck(this.session, messageInfo, this.connection.Last); if (fault == null) { // Received valid final ack after sending Close, inform the close thread. this.closeRequestor.SetInfo(messageInfo); } else { // Received invalid final ack after sending Close, fault. this.session.OnLocalFault(fault.CreateException(), fault, null); } } return; } int bufferRemaining = -1; if (this.settings.FlowControlEnabled) { bufferRemaining = messageInfo.AcknowledgementInfo.BufferRemaining; } // We accept no more than MaxSequenceRanges ranges to limit the serialized ack size and // the amount of memory taken up by the ack ranges. Since request reply uses the presence of // a reply as an acknowledgement we cannot call ProcessTransferred (which stops retrying the // request) if we intend to drop the message. This means the limit is not strict since we do // not check for the limit and merge the ranges atomically. The limit + the number of // concurrent threads is a sufficient mitigation. if ((messageInfo.SequencedMessageInfo != null) && !ReliableInputConnection.CanMerge(messageInfo.SequencedMessageInfo.SequenceNumber, this.ranges)) { messageInfo.Message.Close(); return; } bool exitGuard = this.replyAckConsistencyGuard != null?this.replyAckConsistencyGuard.Enter() : false; try { this.connection.ProcessTransferred(requestSequenceNumber, messageInfo.AcknowledgementInfo.Ranges, bufferRemaining); this.session.OnRemoteActivity(this.connection.Strategy.QuotaRemaining == 0); if (messageInfo.SequencedMessageInfo != null) { lock (this.ThisLock) { this.ranges = this.ranges.MergeWith(messageInfo.SequencedMessageInfo.SequenceNumber); } } } finally { if (exitGuard) { this.replyAckConsistencyGuard.Exit(); } } if (request != null) { if (WsrmUtilities.IsWsrmAction(this.settings.ReliableMessagingVersion, messageInfo.Action)) { messageInfo.Message.Close(); request.Set(null); } else { request.Set(messageInfo.Message); } } // The termination mechanism in the TerminateSequence fails with RequestReply. // Since the ack ranges are updated after ProcessTransferred is called and // ProcessTransferred potentially signals the Termination process, this channel // winds up sending a message with the ack for last message missing. // Thus we send the termination after we update the ranges. if ((this.shutdownHandle != null) && this.connection.CheckForTermination()) { this.shutdownHandle.Set(); } if (request != null) { request.Complete(); } }
public Message WaitForReply(TimeSpan timeout) { bool throwing = true; try { bool expired = false; if (!this.completed) { bool wait = false; lock (this.ThisLock) { if (!this.completed) { wait = true; this.completedHandle = new ManualResetEvent(false); } } if (wait) { expired = !TimeoutHelper.WaitOne(this.completedHandle, timeout); lock (this.ThisLock) { if (!this.completed) { this.completed = true; } else { expired = false; } } this.completedHandle.Close(); } } if (this.aborted) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(this.parent.CreateClosedException()); } else if (this.faulted) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(this.parent.GetTerminalException()); } else if (expired) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new TimeoutException(SR.GetString(SR.TimeoutOnRequest, this.originalTimeout))); } else { throwing = false; return(this.reply); } } finally { if (throwing) { WsrmFault fault = SequenceTerminatedFault.CreateCommunicationFault(this.parent.session.InputID, SR.GetString(SR.SequenceTerminatedReliableRequestThrew), null); this.parent.session.OnLocalFault(null, fault, null); if (this.completedHandle != null) { this.completedHandle.Close(); } } } }
protected async Task ProcessMessageAsync(Message message) { bool closeMessage = true; WsrmMessageInfo messageInfo = WsrmMessageInfo.Get(Settings.MessageVersion, Settings.ReliableMessagingVersion, _binder.Channel, _binder.GetInnerSession(), message); bool wsrm11 = Settings.ReliableMessagingVersion == ReliableMessagingVersion.WSReliableMessaging11; try { if (!_session.ProcessInfo(messageInfo, null)) { closeMessage = false; return; } if (!ReliableSession.VerifySimplexProtocolElements(messageInfo, null)) { closeMessage = false; return; } bool final = false; if (messageInfo.AcknowledgementInfo != null) { final = wsrm11 && messageInfo.AcknowledgementInfo.Final; int bufferRemaining = -1; if (Settings.FlowControlEnabled) { bufferRemaining = messageInfo.AcknowledgementInfo.BufferRemaining; } Connection.ProcessTransferred(messageInfo.AcknowledgementInfo.Ranges, bufferRemaining); } if (wsrm11) { WsrmFault fault = null; if (messageInfo.TerminateSequenceResponseInfo != null) { fault = WsrmUtilities.ValidateTerminateSequenceResponse(_session, _terminateRequestor.MessageId, messageInfo, Connection.Last); if (fault == null) { fault = ProcessRequestorResponse(_terminateRequestor, WsrmFeb2005Strings.TerminateSequence, messageInfo); } } else if (messageInfo.CloseSequenceResponseInfo != null) { fault = WsrmUtilities.ValidateCloseSequenceResponse(_session, _closeRequestor.MessageId, messageInfo, Connection.Last); if (fault == null) { fault = ProcessRequestorResponse(_closeRequestor, Wsrm11Strings.CloseSequence, messageInfo); } } else if (messageInfo.TerminateSequenceInfo != null) { if (!WsrmUtilities.ValidateWsrmRequest(_session, messageInfo.TerminateSequenceInfo, _binder, null)) { return; } WsrmAcknowledgmentInfo ackInfo = messageInfo.AcknowledgementInfo; fault = WsrmUtilities.ValidateFinalAckExists(_session, ackInfo); if ((fault == null) && !Connection.IsFinalAckConsistent(ackInfo.Ranges)) { fault = new InvalidAcknowledgementFault(_session.OutputID, ackInfo.Ranges); } if (fault == null) { Message response = WsrmUtilities.CreateTerminateResponseMessage( Settings.MessageVersion, messageInfo.TerminateSequenceInfo.MessageId, _session.OutputID); try { await OnConnectionSendAsync(response, DefaultSendTimeout, false, true); } finally { response.Close(); } _session.OnRemoteFault(new ProtocolException(SR.UnsupportedTerminateSequenceExceptionString)); return; } } else if (final) { if (_closeRequestor == null) { string exceptionString = SR.UnsupportedCloseExceptionString; string faultString = SR.SequenceTerminatedUnsupportedClose; fault = SequenceTerminatedFault.CreateProtocolFault(_session.OutputID, faultString, exceptionString); } else { fault = WsrmUtilities.ValidateFinalAck(_session, messageInfo, Connection.Last); if (fault == null) { _closeRequestor.SetInfo(messageInfo); } } } else if (messageInfo.WsrmHeaderFault != null) { if (!(messageInfo.WsrmHeaderFault is UnknownSequenceFault)) { throw Fx.AssertAndThrow("Fault must be UnknownSequence fault."); } if (_terminateRequestor == null) { throw Fx.AssertAndThrow("In wsrm11, if we start getting UnknownSequence, terminateRequestor cannot be null."); } _terminateRequestor.SetInfo(messageInfo); } if (fault != null) { _session.OnLocalFault(fault.CreateException(), fault, null); return; } } _session.OnRemoteActivity(Connection.Strategy.QuotaRemaining == 0); } finally { if (closeMessage) { messageInfo.Message.Close(); } } }