private void ProcessCloseOrTerminateReply(bool close, Message reply)
        {
            if (reply == null)
            {
                throw Fx.AssertAndThrow("Argument reply cannot be null.");
            }
            ReliableRequestor requestor = close ? this.closeRequestor : this.terminateRequestor;

            if (requestor.GetInfo() == null)
            {
                try
                {
                    WsrmMessageInfo info = WsrmMessageInfo.Get(this.Settings.MessageVersion, this.Settings.ReliableMessagingVersion, this.binder.Channel, this.binder.GetInnerSession(), reply);
                    this.ReliableSession.ProcessInfo(info, null, true);
                    this.ReliableSession.VerifyDuplexProtocolElements(info, null, true);
                    WsrmFault fault = close ? WsrmUtilities.ValidateCloseSequenceResponse(this.session, requestor.MessageId, info, this.connection.Last) : WsrmUtilities.ValidateTerminateSequenceResponse(this.session, requestor.MessageId, info, this.connection.Last);
                    if (fault != null)
                    {
                        this.ReliableSession.OnLocalFault(null, fault, null);
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(fault.CreateException());
                    }
                }
                finally
                {
                    reply.Close();
                }
            }
        }
        protected override bool HandleReceiveComplete(IAsyncResult result)
        {
            RequestContext context;

            if (!base.Binder.EndTryReceive(result, out context))
            {
                return(true);
            }
            if (context == null)
            {
                bool flag2 = false;
                lock (base.ThisLock)
                {
                    flag2 = base.Connection.Terminate();
                }
                if (!flag2 && (base.Binder.State == CommunicationState.Opened))
                {
                    Exception e = new CommunicationException(System.ServiceModel.SR.GetString("EarlySecurityClose"));
                    base.ReliableSession.OnLocalFault(e, (Message)null, null);
                }
                return(false);
            }
            WsrmMessageInfo info = WsrmMessageInfo.Get(base.Listener.MessageVersion, base.Listener.ReliableMessagingVersion, base.Binder.Channel, base.Binder.GetInnerSession(), context.RequestMessage);

            base.StartReceiving(false);
            this.ProcessRequest(context, info);
            return(false);
        }
        private bool HandleReceiveComplete(TItem item, TInnerChannel channel)
        {
            Message          message = null;
            TReliableChannel local;
            bool             flag;
            bool             flag2;

            try
            {
                message = this.GetMessage(item);
            }
            catch (Exception exception)
            {
                if (Fx.IsFatal(exception))
                {
                    throw;
                }
                if (!base.HandleException(exception, this))
                {
                    throw;
                }
                item.Dispose();
                return(true);
            }
            WsrmMessageInfo info = WsrmMessageInfo.Get(base.MessageVersion, base.ReliableMessagingVersion, channel, null, message);

            if (info.ParsingException != null)
            {
                this.DisposeItem(item);
                return(true);
            }
            if (!this.BeginProcessItem(item, info, channel, out local, out flag, out flag2))
            {
                return(false);
            }
            if (local == null)
            {
                this.DisposeItem(item);
                return(true);
            }
            if (flag2 || !flag)
            {
                this.StartReceiving(channel, false);
                this.EndProcessItem(item, info, local, flag2);
                return(false);
            }
            this.EndProcessItem(item, info, local, flag2);
            return(true);
        }
        private void ProcessCloseOrTerminateReply(bool close, Message reply)
        {
            if (reply == null)
            {
                throw Fx.AssertAndThrow("Argument reply cannot be null.");
            }
            ReliableMessagingVersion reliableMessagingVersion = this.settings.ReliableMessagingVersion;

            if (reliableMessagingVersion == ReliableMessagingVersion.WSReliableMessagingFebruary2005)
            {
                if (close)
                {
                    throw Fx.AssertAndThrow("Close does not exist in Feb2005.");
                }
                reply.Close();
            }
            else
            {
                if (reliableMessagingVersion == ReliableMessagingVersion.WSReliableMessaging11)
                {
                    if (this.closeRequestor.GetInfo() != null)
                    {
                        return;
                    }
                    try
                    {
                        WsrmMessageInfo info = WsrmMessageInfo.Get(this.settings.MessageVersion, reliableMessagingVersion, this.binder.Channel, this.binder.GetInnerSession(), reply);
                        this.session.ProcessInfo(info, null, true);
                        this.session.VerifyDuplexProtocolElements(info, null, true);
                        WsrmFault fault = close ? WsrmUtilities.ValidateCloseSequenceResponse(this.session, this.closeRequestor.MessageId, info, this.connection.Last) : WsrmUtilities.ValidateTerminateSequenceResponse(this.session, this.terminateRequestor.MessageId, info, this.connection.Last);
                        if (fault != null)
                        {
                            this.session.OnLocalFault(null, fault, null);
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(fault.CreateException());
                        }
                        return;
                    }
                    finally
                    {
                        reply.Close();
                    }
                }
                throw Fx.AssertAndThrow("Reliable messaging version not supported.");
            }
        }
        private void ProcessCloseOrTerminateReply(bool close, Message reply)
        {
            if (reply == null)
            {
                // In the close case, the requestor is configured to throw TimeoutException instead of returning null.
                // In the terminate case, this value can be null, but the caller should not call this method.
                throw Fx.AssertAndThrow("Argument reply cannot be null.");
            }

            ReliableRequestor requestor = close ? _closeRequestor : _terminateRequestor;
            WsrmMessageInfo   info      = requestor.GetInfo();

            // Some other thread has verified and cleaned up the reply, no more work to do.
            if (info != null)
            {
                return;
            }

            try
            {
                info = WsrmMessageInfo.Get(Settings.MessageVersion, Settings.ReliableMessagingVersion,
                                           _binder.Channel, _binder.GetInnerSession(), reply);
                ReliableSession.ProcessInfo(info, null, true);
                ReliableSession.VerifyDuplexProtocolElements(info, null, true);

                WsrmFault fault = close
                    ? WsrmUtilities.ValidateCloseSequenceResponse(_session, requestor.MessageId, info,
                                                                  Connection.Last)
                    : WsrmUtilities.ValidateTerminateSequenceResponse(_session, requestor.MessageId, info,
                                                                      Connection.Last);

                if (fault != null)
                {
                    ReliableSession.OnLocalFault(null, fault, null);
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(fault.CreateException());
                }
            }
            finally
            {
                reply.Close();
            }
        }
        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();
            }
        }
        void ProcessCloseOrTerminateReply(bool close, Message reply)
        {
            if (reply == null)
            {
                // In the close case, the requestor is configured to throw TimeoutException instead of returning null.
                // In the terminate case, this value can be null, but the caller should not call this method.
                throw Fx.AssertAndThrow("Argument reply cannot be null.");
            }

            ReliableMessagingVersion reliableMessagingVersion = this.settings.ReliableMessagingVersion;

            if (reliableMessagingVersion == ReliableMessagingVersion.WSReliableMessagingFebruary2005)
            {
                if (close)
                {
                    throw Fx.AssertAndThrow("Close does not exist in Feb2005.");
                }

                reply.Close();
            }
            else if (reliableMessagingVersion == ReliableMessagingVersion.WSReliableMessaging11)
            {
                WsrmMessageInfo info = this.closeRequestor.GetInfo();

                // Close - Final ack made it.
                // Terminate - UnknownSequence.
                // Either way, message has been verified and does not belong to this thread.
                if (info != null)
                {
                    return;
                }

                try
                {
                    info = WsrmMessageInfo.Get(this.settings.MessageVersion, reliableMessagingVersion,
                                               this.binder.Channel, this.binder.GetInnerSession(), reply);
                    this.session.ProcessInfo(info, null, true);
                    this.session.VerifyDuplexProtocolElements(info, null, true);

                    WsrmFault fault = close
                        ? WsrmUtilities.ValidateCloseSequenceResponse(this.session, this.closeRequestor.MessageId, info,
                                                                      this.connection.Last)
                        : WsrmUtilities.ValidateTerminateSequenceResponse(this.session, this.terminateRequestor.MessageId,
                                                                          info, this.connection.Last);

                    if (fault != null)
                    {
                        this.session.OnLocalFault(null, fault, null);
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(fault.CreateException());
                    }
                }
                finally
                {
                    reply.Close();
                }
            }
            else
            {
                throw Fx.AssertAndThrow("Reliable messaging version not supported.");
            }
        }
        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();
                }
            }
        }
        private void ProcessReply(Message reply, IReliableRequest request, long requestSequenceNumber)
        {
            WsrmMessageInfo info = WsrmMessageInfo.Get(this.settings.MessageVersion, this.settings.ReliableMessagingVersion, this.binder.Channel, this.binder.GetInnerSession(), reply);

            if (this.session.ProcessInfo(info, null) && this.session.VerifyDuplexProtocolElements(info, null))
            {
                bool flag = this.settings.ReliableMessagingVersion == ReliableMessagingVersion.WSReliableMessaging11;
                if (info.WsrmHeaderFault != null)
                {
                    info.Message.Close();
                    if (!(info.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(info);
                }
                else if (info.AcknowledgementInfo == null)
                {
                    WsrmFault fault = SequenceTerminatedFault.CreateProtocolFault(this.session.InputID, System.ServiceModel.SR.GetString("SequenceTerminatedReplyMissingAcknowledgement"), System.ServiceModel.SR.GetString("ReplyMissingAcknowledgement"));
                    info.Message.Close();
                    this.session.OnLocalFault(fault.CreateException(), fault, null);
                }
                else if (flag && (info.TerminateSequenceInfo != null))
                {
                    UniqueId  sequenceID = (info.TerminateSequenceInfo.Identifier == this.session.OutputID) ? this.session.InputID : this.session.OutputID;
                    WsrmFault fault2     = SequenceTerminatedFault.CreateProtocolFault(sequenceID, System.ServiceModel.SR.GetString("SequenceTerminatedUnsupportedTerminateSequence"), System.ServiceModel.SR.GetString("UnsupportedTerminateSequenceExceptionString"));
                    info.Message.Close();
                    this.session.OnLocalFault(fault2.CreateException(), fault2, null);
                }
                else if (flag && info.AcknowledgementInfo.Final)
                {
                    info.Message.Close();
                    if (this.closeRequestor == null)
                    {
                        string    exceptionMessage = System.ServiceModel.SR.GetString("UnsupportedCloseExceptionString");
                        string    faultReason      = System.ServiceModel.SR.GetString("SequenceTerminatedUnsupportedClose");
                        WsrmFault fault3           = SequenceTerminatedFault.CreateProtocolFault(this.session.OutputID, faultReason, exceptionMessage);
                        this.session.OnLocalFault(fault3.CreateException(), fault3, null);
                    }
                    else
                    {
                        WsrmFault fault4 = WsrmUtilities.ValidateFinalAck(this.session, info, this.connection.Last);
                        if (fault4 == null)
                        {
                            this.closeRequestor.SetInfo(info);
                        }
                        else
                        {
                            this.session.OnLocalFault(fault4.CreateException(), fault4, null);
                        }
                    }
                }
                else
                {
                    int quotaRemaining = -1;
                    if (this.settings.FlowControlEnabled)
                    {
                        quotaRemaining = info.AcknowledgementInfo.BufferRemaining;
                    }
                    if ((info.SequencedMessageInfo != null) && !ReliableInputConnection.CanMerge(info.SequencedMessageInfo.SequenceNumber, this.ranges))
                    {
                        info.Message.Close();
                    }
                    else
                    {
                        bool flag2 = (this.replyAckConsistencyGuard != null) ? this.replyAckConsistencyGuard.Enter() : false;
                        try
                        {
                            this.connection.ProcessTransferred(requestSequenceNumber, info.AcknowledgementInfo.Ranges, quotaRemaining);
                            this.session.OnRemoteActivity(this.connection.Strategy.QuotaRemaining == 0);
                            if (info.SequencedMessageInfo != null)
                            {
                                lock (base.ThisLock)
                                {
                                    this.ranges = this.ranges.MergeWith(info.SequencedMessageInfo.SequenceNumber);
                                }
                            }
                        }
                        finally
                        {
                            if (flag2)
                            {
                                this.replyAckConsistencyGuard.Exit();
                            }
                        }
                        if (request != null)
                        {
                            if (WsrmUtilities.IsWsrmAction(this.settings.ReliableMessagingVersion, info.Action))
                            {
                                info.Message.Close();
                                request.Set(null);
                            }
                            else
                            {
                                request.Set(info.Message);
                            }
                        }
                        if ((this.shutdownHandle != null) && this.connection.CheckForTermination())
                        {
                            this.shutdownHandle.Set();
                        }
                        if (request != null)
                        {
                            request.Complete();
                        }
                    }
                }
            }
        }
Exemple #10
0
        private void HandleReceiveComplete(TItem item, TInnerChannel channel)
        {
            WsrmMessageInfo info = WsrmMessageInfo.Get(base.MessageVersion, base.ReliableMessagingVersion, channel, channel.Session as ISecureConversationSession, this.GetMessage(item));

            if (info.ParsingException != null)
            {
                this.DisposeItem(item);
                channel.Abort();
            }
            else
            {
                TReliableChannel reliableChannel = default(TReliableChannel);
                bool             dispatch        = false;
                bool             newChannel      = false;
                Message          reply           = null;
                if (info.FaultReply != null)
                {
                    reply = info.FaultReply;
                }
                else if (info.CreateSequenceInfo == null)
                {
                    UniqueId id;
                    reliableChannel = base.GetChannel(info, out id);
                    if ((reliableChannel == null) && (id == null))
                    {
                        this.DisposeItem(item);
                        channel.Abort();
                        return;
                    }
                    if (reliableChannel == null)
                    {
                        reply = new UnknownSequenceFault(id).CreateMessage(base.MessageVersion, base.ReliableMessagingVersion);
                    }
                }
                else
                {
                    reliableChannel = base.ProcessCreateSequence(info, channel, out dispatch, out newChannel);
                    if (reliableChannel == null)
                    {
                        reply = info.FaultReply;
                    }
                }
                if (reliableChannel != null)
                {
                    this.ProcessSequencedItem(channel, item, reliableChannel, info, newChannel);
                    if (dispatch)
                    {
                        base.Dispatch();
                    }
                }
                else
                {
                    try
                    {
                        this.SendReply(reply, channel, item);
                        channel.Close();
                    }
                    catch (Exception exception)
                    {
                        if (Fx.IsFatal(exception))
                        {
                            throw;
                        }
                        if (DiagnosticUtility.ShouldTraceError)
                        {
                            DiagnosticUtility.ExceptionUtility.TraceHandledException(exception, TraceEventType.Error);
                        }
                        channel.Abort();
                    }
                    finally
                    {
                        reply.Close();
                        this.DisposeItem(item);
                    }
                }
            }
        }
        private void ProcessCreateSequenceResponse(Message response, DateTime start)
        {
            CreateSequenceResponseInfo createSequenceResponseInfo = null;

            using (response)
            {
                if (response.IsFault)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(WsrmUtilities.CreateCSFaultException(base.Settings.MessageVersion, base.Settings.ReliableMessagingVersion, response, this.binder.Channel));
                }
                WsrmMessageInfo info2 = WsrmMessageInfo.Get(base.Settings.MessageVersion, base.Settings.ReliableMessagingVersion, this.binder.Channel, this.binder.GetInnerSession(), response, true);
                if (info2.ParsingException != null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ProtocolException(System.ServiceModel.SR.GetString("UnparsableCSResponse"), info2.ParsingException));
                }
                base.ProcessInfo(info2, null, true);
                createSequenceResponseInfo = info2.CreateSequenceResponseInfo;
                string message     = null;
                string faultReason = null;
                if (createSequenceResponseInfo == null)
                {
                    message = System.ServiceModel.SR.GetString("InvalidWsrmResponseChannelNotOpened", new object[] { "CreateSequence", info2.Action, WsrmIndex.GetCreateSequenceResponseActionString(base.Settings.ReliableMessagingVersion) });
                }
                else if (!object.Equals(createSequenceResponseInfo.RelatesTo, this.requestor.MessageId))
                {
                    message     = System.ServiceModel.SR.GetString("WsrmMessageWithWrongRelatesToExceptionString", new object[] { "CreateSequence" });
                    faultReason = System.ServiceModel.SR.GetString("WsrmMessageWithWrongRelatesToFaultString", new object[] { "CreateSequence" });
                }
                else if ((createSequenceResponseInfo.AcceptAcksTo == null) && (base.InputID != null))
                {
                    if (base.Settings.ReliableMessagingVersion != ReliableMessagingVersion.WSReliableMessagingFebruary2005)
                    {
                        if (base.Settings.ReliableMessagingVersion != ReliableMessagingVersion.WSReliableMessaging11)
                        {
                            throw Fx.AssertAndThrow("Reliable messaging version not supported.");
                        }
                        message     = System.ServiceModel.SR.GetString("CSResponseOfferRejected");
                        faultReason = System.ServiceModel.SR.GetString("CSResponseOfferRejectedReason");
                    }
                    else
                    {
                        message     = System.ServiceModel.SR.GetString("CSResponseWithoutOffer");
                        faultReason = System.ServiceModel.SR.GetString("CSResponseWithoutOfferReason");
                    }
                }
                else if ((createSequenceResponseInfo.AcceptAcksTo != null) && (base.InputID == null))
                {
                    message     = System.ServiceModel.SR.GetString("CSResponseWithOffer");
                    faultReason = System.ServiceModel.SR.GetString("CSResponseWithOfferReason");
                }
                else if ((createSequenceResponseInfo.AcceptAcksTo != null) && (createSequenceResponseInfo.AcceptAcksTo.Uri != this.binder.RemoteAddress.Uri))
                {
                    message     = System.ServiceModel.SR.GetString("AcksToMustBeSameAsRemoteAddress");
                    faultReason = System.ServiceModel.SR.GetString("AcksToMustBeSameAsRemoteAddressReason");
                }
                if ((faultReason != null) && (createSequenceResponseInfo != null))
                {
                    WsrmFault fault = SequenceTerminatedFault.CreateProtocolFault(createSequenceResponseInfo.Identifier, faultReason, null);
                    base.OnLocalFault(null, fault, null);
                }
                if (message != null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ProtocolException(message));
                }
            }
            base.InitiationTime = (TimeSpan)(DateTime.UtcNow - start);
            base.OutputID       = createSequenceResponseInfo.Identifier;
            this.pollingTimer.Set(this.GetPollingInterval());
            base.StartInactivityTimer();
        }
        protected void ProcessMessage(Message message)
        {
            bool            flag  = true;
            WsrmMessageInfo info  = WsrmMessageInfo.Get(this.settings.MessageVersion, this.settings.ReliableMessagingVersion, this.binder.Channel, this.binder.GetInnerSession(), message);
            bool            flag2 = this.settings.ReliableMessagingVersion == ReliableMessagingVersion.WSReliableMessaging11;

            try
            {
                if (!this.session.ProcessInfo(info, null))
                {
                    flag = false;
                    return;
                }
                if (!this.ReliableSession.VerifySimplexProtocolElements(info, null))
                {
                    flag = false;
                    return;
                }
                bool flag3 = false;
                if (info.AcknowledgementInfo != null)
                {
                    flag3 = flag2 && info.AcknowledgementInfo.Final;
                    int quotaRemaining = -1;
                    if (this.settings.FlowControlEnabled)
                    {
                        quotaRemaining = info.AcknowledgementInfo.BufferRemaining;
                    }
                    this.connection.ProcessTransferred(info.AcknowledgementInfo.Ranges, quotaRemaining);
                }
                if (!flag2)
                {
                    goto Label_0300;
                }
                WsrmFault fault = null;
                if (info.TerminateSequenceResponseInfo != null)
                {
                    fault = WsrmUtilities.ValidateTerminateSequenceResponse(this.session, this.terminateRequestor.MessageId, info, this.connection.Last);
                    if (fault == null)
                    {
                        fault = this.ProcessRequestorResponse(this.terminateRequestor, "TerminateSequence", info);
                    }
                }
                else if (info.CloseSequenceResponseInfo != null)
                {
                    fault = WsrmUtilities.ValidateCloseSequenceResponse(this.session, this.closeRequestor.MessageId, info, this.connection.Last);
                    if (fault == null)
                    {
                        fault = this.ProcessRequestorResponse(this.closeRequestor, "CloseSequence", info);
                    }
                }
                else
                {
                    if (info.TerminateSequenceInfo != null)
                    {
                        if (WsrmUtilities.ValidateWsrmRequest(this.session, info.TerminateSequenceInfo, this.binder, null))
                        {
                            WsrmAcknowledgmentInfo acknowledgementInfo = info.AcknowledgementInfo;
                            fault = WsrmUtilities.ValidateFinalAckExists(this.session, acknowledgementInfo);
                            if ((fault == null) && !this.connection.IsFinalAckConsistent(acknowledgementInfo.Ranges))
                            {
                                fault = new InvalidAcknowledgementFault(this.session.OutputID, acknowledgementInfo.Ranges);
                            }
                            if (fault != null)
                            {
                                goto Label_02E5;
                            }
                            Message message2 = WsrmUtilities.CreateTerminateResponseMessage(this.settings.MessageVersion, info.TerminateSequenceInfo.MessageId, this.session.OutputID);
                            try
                            {
                                this.OnConnectionSend(message2, base.DefaultSendTimeout, false, true);
                            }
                            finally
                            {
                                message2.Close();
                            }
                            this.session.OnRemoteFault(new ProtocolException(System.ServiceModel.SR.GetString("UnsupportedTerminateSequenceExceptionString")));
                        }
                        return;
                    }
                    if (flag3)
                    {
                        if (this.closeRequestor == null)
                        {
                            string exceptionMessage = System.ServiceModel.SR.GetString("UnsupportedCloseExceptionString");
                            string faultReason      = System.ServiceModel.SR.GetString("SequenceTerminatedUnsupportedClose");
                            fault = SequenceTerminatedFault.CreateProtocolFault(this.session.OutputID, faultReason, exceptionMessage);
                        }
                        else
                        {
                            fault = WsrmUtilities.ValidateFinalAck(this.session, info, this.connection.Last);
                            if (fault == null)
                            {
                                this.closeRequestor.SetInfo(info);
                            }
                        }
                    }
                    else if (info.WsrmHeaderFault != null)
                    {
                        if (!(info.WsrmHeaderFault is UnknownSequenceFault))
                        {
                            throw Fx.AssertAndThrow("Fault must be UnknownSequence fault.");
                        }
                        if (this.terminateRequestor == null)
                        {
                            throw Fx.AssertAndThrow("In wsrm11, if we start getting UnknownSequence, terminateRequestor cannot be null.");
                        }
                        this.terminateRequestor.SetInfo(info);
                    }
                }
Label_02E5:
                if (fault != null)
                {
                    this.session.OnLocalFault(fault.CreateException(), fault, null);
                    return;
                }
Label_0300:
                this.session.OnRemoteActivity(this.connection.Strategy.QuotaRemaining == 0);
            }
            finally
            {
                if (flag)
                {
                    info.Message.Close();
                }
            }
        }
        void ProcessCreateSequenceResponse(Message response, DateTime start)
        {
            CreateSequenceResponseInfo createResponse = null;

            using (response)
            {
                if (response.IsFault)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(WsrmUtilities.CreateCSFaultException(
                                                                                  this.Settings.MessageVersion, this.Settings.ReliableMessagingVersion, response,
                                                                                  this.binder.Channel));
                }
                else
                {
                    WsrmMessageInfo info = WsrmMessageInfo.Get(this.Settings.MessageVersion,
                                                               this.Settings.ReliableMessagingVersion, this.binder.Channel, this.binder.GetInnerSession(),
                                                               response, true);

                    if (info.ParsingException != null)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ProtocolException(SR.GetString(SR.UnparsableCSResponse), info.ParsingException));
                    }

                    // this throws and sends a fault if something is wrong with the info
                    this.ProcessInfo(info, null, true);
                    createResponse = info.CreateSequenceResponseInfo;

                    string exceptionReason = null;
                    string faultReason     = null;

                    if (createResponse == null)
                    {
                        exceptionReason = SR.GetString(SR.InvalidWsrmResponseChannelNotOpened,
                                                       WsrmFeb2005Strings.CreateSequence, info.Action,
                                                       WsrmIndex.GetCreateSequenceResponseActionString(this.Settings.ReliableMessagingVersion));
                    }
                    else if (!object.Equals(createResponse.RelatesTo, this.requestor.MessageId))
                    {
                        exceptionReason = SR.GetString(SR.WsrmMessageWithWrongRelatesToExceptionString, WsrmFeb2005Strings.CreateSequence);
                        faultReason     = SR.GetString(SR.WsrmMessageWithWrongRelatesToFaultString, WsrmFeb2005Strings.CreateSequence);
                    }
                    else if ((createResponse.AcceptAcksTo == null) && (this.InputID != null))
                    {
                        if (this.Settings.ReliableMessagingVersion == ReliableMessagingVersion.WSReliableMessagingFebruary2005)
                        {
                            exceptionReason = SR.GetString(SR.CSResponseWithoutOffer);
                            faultReason     = SR.GetString(SR.CSResponseWithoutOfferReason);
                        }
                        else if (this.Settings.ReliableMessagingVersion == ReliableMessagingVersion.WSReliableMessaging11)
                        {
                            exceptionReason = SR.GetString(SR.CSResponseOfferRejected);
                            faultReason     = SR.GetString(SR.CSResponseOfferRejectedReason);
                        }
                        else
                        {
                            throw Fx.AssertAndThrow("Reliable messaging version not supported.");
                        }
                    }
                    else if ((createResponse.AcceptAcksTo != null) && (this.InputID == null))
                    {
                        exceptionReason = SR.GetString(SR.CSResponseWithOffer);
                        faultReason     = SR.GetString(SR.CSResponseWithOfferReason);
                    }
                    else if (createResponse.AcceptAcksTo != null && (createResponse.AcceptAcksTo.Uri != this.binder.RemoteAddress.Uri))
                    {
                        exceptionReason = SR.GetString(SR.AcksToMustBeSameAsRemoteAddress);
                        faultReason     = SR.GetString(SR.AcksToMustBeSameAsRemoteAddressReason);
                    }

                    if ((faultReason != null) && (createResponse != null))
                    {
                        UniqueId  sequenceId = createResponse.Identifier;
                        WsrmFault fault      = SequenceTerminatedFault.CreateProtocolFault(sequenceId, faultReason, null);
                        this.OnLocalFault(null, fault, null);
                    }

                    if (exceptionReason != null)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ProtocolException(exceptionReason));
                    }
                }
            }

            this.InitiationTime = DateTime.UtcNow - start;
            this.OutputID       = createResponse.Identifier;
            this.pollingTimer.Set(this.GetPollingInterval());
            base.StartInactivityTimer();
        }