internal static void WriteAckRanges(XmlDictionaryWriter writer, ReliableMessagingVersion reliableMessagingVersion, UniqueId sequenceId, SequenceRangeCollection ranges)
 {
     WsrmFeb2005Dictionary dictionary = XD.WsrmFeb2005Dictionary;
     XmlDictionaryString namespaceUri = WsrmIndex.GetNamespace(reliableMessagingVersion);
     writer.WriteStartElement(dictionary.Identifier, namespaceUri);
     writer.WriteValue(sequenceId);
     writer.WriteEndElement();
     if (ranges.Count == 0)
     {
         if (reliableMessagingVersion == ReliableMessagingVersion.WSReliableMessagingFebruary2005)
         {
             ranges = ranges.MergeWith((long) 0L);
         }
         else if (reliableMessagingVersion == ReliableMessagingVersion.WSReliableMessaging11)
         {
             writer.WriteStartElement(DXD.Wsrm11Dictionary.None, namespaceUri);
             writer.WriteEndElement();
         }
     }
     for (int i = 0; i < ranges.Count; i++)
     {
         writer.WriteStartElement(dictionary.AcknowledgementRange, namespaceUri);
         writer.WriteStartAttribute(dictionary.Lower, null);
         SequenceRange range = ranges[i];
         writer.WriteValue(range.Lower);
         writer.WriteEndAttribute();
         writer.WriteStartAttribute(dictionary.Upper, null);
         SequenceRange range2 = ranges[i];
         writer.WriteValue(range2.Upper);
         writer.WriteEndAttribute();
         writer.WriteEndElement();
     }
 }
 private WsrmAcknowledgmentInfo(UniqueId sequenceID, SequenceRangeCollection ranges, bool final, int bufferRemaining, MessageHeaderInfo header) : base(header)
 {
     this.sequenceID = sequenceID;
     this.ranges = ranges;
     this.final = final;
     this.bufferRemaining = bufferRemaining;
 }
 public WsrmAcknowledgmentHeader(ReliableMessagingVersion reliableMessagingVersion, UniqueId sequenceID, SequenceRangeCollection ranges, bool final, int bufferRemaining) : base(reliableMessagingVersion)
 {
     this.sequenceID = sequenceID;
     this.ranges = ranges;
     this.final = final;
     this.bufferRemaining = bufferRemaining;
 }
 public static bool CanMerge(long sequenceNumber, SequenceRangeCollection ranges)
 {
     if (ranges.Count < ReliableMessagingConstants.MaxSequenceRanges)
     {
         return true;
     }
     ranges = ranges.MergeWith(sequenceNumber);
     return (ranges.Count <= ReliableMessagingConstants.MaxSequenceRanges);
 }
 public void ProcessAcknowledgement(SequenceRangeCollection ranges, out bool invalidAck, out bool inconsistentAck)
 {
     invalidAck = false;
     inconsistentAck = false;
     bool flag = false;
     bool flag2 = false;
     lock (this.ThisLock)
     {
         if (this.closed)
         {
             return;
         }
         long num = (this.windowStart + this.window.Count) - 1L;
         long num2 = this.windowStart - 1L;
         int transferredCount = this.window.TransferredCount;
         for (int i = 0; i < ranges.Count; i++)
         {
             SequenceRange range = ranges[i];
             if (range.Upper > num)
             {
                 invalidAck = true;
                 return;
             }
             if (((range.Lower > 1L) && (range.Lower <= num2)) || (range.Upper < num2))
             {
                 flag2 = true;
             }
             if (range.Upper >= this.windowStart)
             {
                 if (range.Lower <= this.windowStart)
                 {
                     flag = true;
                 }
                 if (!flag)
                 {
                     int beginIndex = (int) (range.Lower - this.windowStart);
                     int endIndex = (range.Upper > num) ? (this.window.Count - 1) : ((int) (range.Upper - this.windowStart));
                     flag = this.window.GetTransferredInRangeCount(beginIndex, endIndex) < ((endIndex - beginIndex) + 1);
                 }
                 if ((transferredCount > 0) && !flag2)
                 {
                     int num7 = (range.Lower < this.windowStart) ? ((int) 0L) : ((int) (range.Lower - this.windowStart));
                     int num8 = (range.Upper > num) ? (this.window.Count - 1) : ((int) (range.Upper - this.windowStart));
                     transferredCount -= this.window.GetTransferredInRangeCount(num7, num8);
                 }
             }
         }
         if (transferredCount > 0)
         {
             flag2 = true;
         }
     }
     inconsistentAck = flag2 && flag;
 }
 public bool IsFinalAckConsistent(SequenceRangeCollection ranges)
 {
     lock (this.ThisLock)
     {
         SequenceRange range2;
         if (this.closed)
         {
             return true;
         }
         if ((this.windowStart == 1L) && (this.window.Count == 0))
         {
             return (ranges.Count == 0);
         }
         if (ranges.Count != 0)
         {
             SequenceRange range = ranges[0];
             if (range.Lower == 1L)
             {
                 goto Label_005F;
             }
         }
         return false;
     Label_005F:
         range2 = ranges[0];
         return (range2.Upper >= (this.windowStart - 1L));
     }
 }
Exemplo n.º 7
0
 public InvalidAcknowledgementFault(UniqueId sequenceID, SequenceRangeCollection ranges)
     : base(true, WsrmFeb2005Strings.InvalidAcknowledgement, SR.GetString(SR.InvalidAcknowledgementFaultReason),
     SR.GetString(SR.InvalidAcknowledgementReceived), sequenceID, true, false)
 {
     this.ranges = ranges;
 }
 public void SetFinalAck(SequenceRangeCollection finalRanges)
 {
     this.finalRanges = finalRanges;
 }
 public InvalidAcknowledgementFault(UniqueId sequenceID, SequenceRangeCollection ranges) : base(true, "InvalidAcknowledgement", System.ServiceModel.SR.GetString("InvalidAcknowledgementFaultReason"), System.ServiceModel.SR.GetString("InvalidAcknowledgementReceived"), sequenceID, true, false)
 {
     this.ranges = ranges;
 }
        public void ProcessAcknowledgement(SequenceRangeCollection ranges, out bool invalidAck, out bool inconsistentAck)
        {
            invalidAck = false;
            inconsistentAck = false;
            bool newAck = false;
            bool oldAck = false;

            lock (this.ThisLock)
            {
                if (this.closed)
                {
                    return;
                }

                Int64 lastMessageSent = this.windowStart + this.window.Count - 1;
                Int64 lastMessageAcked = this.windowStart - 1;
                int transferredInWindow = this.window.TransferredCount;

                for (int i = 0; i < ranges.Count; i++)
                {
                    SequenceRange range = ranges[i];

                    // Ack for a message not yet sent.
                    if (range.Upper > lastMessageSent)
                    {
                        invalidAck = true;
                        return;
                    }

                    if (((range.Lower > 1) && (range.Lower <= lastMessageAcked)) || (range.Upper < lastMessageAcked))
                    {
                        oldAck = true;
                    }

                    if (range.Upper >= this.windowStart)
                    {
                        if (range.Lower <= this.windowStart)
                        {
                            newAck = true;
                        }

                        if (!newAck)
                        {
                            int beginIndex = (int)(range.Lower - this.windowStart);
                            int endIndex = (int)((range.Upper > lastMessageSent) ? (this.window.Count - 1) : (range.Upper - this.windowStart));

                            newAck = this.window.GetTransferredInRangeCount(beginIndex, endIndex) < (endIndex - beginIndex + 1);
                        }

                        if (transferredInWindow > 0 && !oldAck)
                        {
                            int beginIndex = (int)((range.Lower < this.windowStart) ? 0 : (range.Lower - this.windowStart));
                            int endIndex = (int)((range.Upper > lastMessageSent) ? (this.window.Count - 1) : (range.Upper - this.windowStart));

                            transferredInWindow -= this.window.GetTransferredInRangeCount(beginIndex, endIndex);
                        }
                    }
                }

                if (transferredInWindow > 0)
                    oldAck = true;
            }

            inconsistentAck = oldAck && newAck;
        }
        public void ProcessTransferred(Int64 transferred, SequenceRangeCollection ranges, int quotaRemaining)
        {
            if (transferred < 0)
            {
                throw Fx.AssertAndThrow("Argument transferred must be a valid sequence number or 0 for protocol messages.");
            }

            bool invalidAck;

            // ignored, TransmissionStrategy is being used to keep track of what must be re-sent.
            // In the Request-Reply case this state may not align with acks.
            bool inconsistentAck;

            this.strategy.ProcessAcknowledgement(ranges, out invalidAck, out inconsistentAck);
            invalidAck = (invalidAck || ((transferred != 0) && !ranges.Contains(transferred)));

            if (!invalidAck)
            {
                if ((transferred > 0) && this.strategy.ProcessTransferred(transferred, quotaRemaining))
                {
                    ActionItem.Schedule(sendRetries, this);
                }
                else
                {
                    this.OnTransferComplete();
                }
            }
            else
            {
                WsrmFault fault = new InvalidAcknowledgementFault(this.id, ranges);
                RaiseFault(fault.CreateException(), fault);
            }
        }
 public void ProcessTransferred(long transferred, SequenceRangeCollection ranges, int quotaRemaining)
 {
     bool flag;
     bool flag2;
     if (transferred < 0L)
     {
         throw Fx.AssertAndThrow("Argument transferred must be a valid sequence number or 0 for protocol messages.");
     }
     this.strategy.ProcessAcknowledgement(ranges, out flag, out flag2);
     if (!flag && ((transferred == 0L) || ranges.Contains(transferred)))
     {
         if ((transferred > 0L) && this.strategy.ProcessTransferred(transferred, quotaRemaining))
         {
             ActionItem.Schedule(sendRetries, this);
         }
         else
         {
             this.OnTransferComplete();
         }
     }
     else
     {
         WsrmFault fault = new InvalidAcknowledgementFault(this.id, ranges);
         this.RaiseFault(fault.CreateException(), fault);
     }
 }
 internal static void ReadAck(ReliableMessagingVersion reliableMessagingVersion, XmlDictionaryReader reader, out UniqueId sequenceId, out SequenceRangeCollection rangeCollection, out bool final)
 {
     WsrmFeb2005Dictionary dictionary = XD.WsrmFeb2005Dictionary;
     XmlDictionaryString namespaceUri = WsrmIndex.GetNamespace(reliableMessagingVersion);
     reader.ReadStartElement(dictionary.SequenceAcknowledgement, namespaceUri);
     reader.ReadStartElement(dictionary.Identifier, namespaceUri);
     sequenceId = reader.ReadContentAsUniqueId();
     reader.ReadEndElement();
     bool allowZero = reliableMessagingVersion == ReliableMessagingVersion.WSReliableMessagingFebruary2005;
     rangeCollection = SequenceRangeCollection.Empty;
     while (reader.IsStartElement(dictionary.AcknowledgementRange, namespaceUri))
     {
         reader.MoveToAttribute("Lower");
         long lower = WsrmUtilities.ReadSequenceNumber(reader, allowZero);
         reader.MoveToAttribute("Upper");
         long upper = WsrmUtilities.ReadSequenceNumber(reader, allowZero);
         if ((((lower < 0L) || (lower > upper)) || (((reliableMessagingVersion == ReliableMessagingVersion.WSReliableMessagingFebruary2005) && (lower == 0L)) && (upper > 0L))) || ((reliableMessagingVersion == ReliableMessagingVersion.WSReliableMessaging11) && (lower == 0L)))
         {
             throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.ServiceModel.SR.GetString("InvalidSequenceRange", new object[] { lower, upper })));
         }
         rangeCollection = rangeCollection.MergeWith(new SequenceRange(lower, upper));
         reader.MoveToElement();
         WsrmUtilities.ReadEmptyElement(reader);
     }
     bool flag2 = rangeCollection.Count > 0;
     final = false;
     if (reliableMessagingVersion == ReliableMessagingVersion.WSReliableMessaging11)
     {
         Wsrm11Dictionary dictionary2 = DXD.Wsrm11Dictionary;
         if (reader.IsStartElement(dictionary2.None, namespaceUri))
         {
             if (flag2)
             {
                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.ServiceModel.SR.GetString("UnexpectedXmlChildNode", new object[] { reader.Name, reader.NodeType, dictionary.SequenceAcknowledgement })));
             }
             WsrmUtilities.ReadEmptyElement(reader);
             flag2 = true;
         }
         if (reader.IsStartElement(dictionary2.Final, namespaceUri))
         {
             if (!flag2)
             {
                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.ServiceModel.SR.GetString("UnexpectedXmlChildNode", new object[] { reader.Name, reader.NodeType, dictionary.SequenceAcknowledgement })));
             }
             WsrmUtilities.ReadEmptyElement(reader);
             final = true;
         }
     }
     bool flag4 = false;
     while (reader.IsStartElement(dictionary.Nack, namespaceUri))
     {
         if (flag2)
         {
             throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.ServiceModel.SR.GetString("UnexpectedXmlChildNode", new object[] { reader.Name, reader.NodeType, "Body" })));
         }
         reader.ReadStartElement();
         WsrmUtilities.ReadSequenceNumber(reader, true);
         reader.ReadEndElement();
         flag4 = true;
     }
     if (!flag2 && !flag4)
     {
         throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.ServiceModel.SR.GetString("UnexpectedXmlChildNode", new object[] { reader.Name, reader.NodeType, "Body" })));
     }
 }
        // Called for Duplex and Output
        public bool ProcessTransferred(SequenceRangeCollection ranges, int quotaRemaining)
        {
            if (ranges.Count == 0)
            {
                return false;
            }

            lock (this.ThisLock)
            {
                if (this.closed)
                {
                    return false;
                }

                bool send = false;

                for (int rangeIndex = 0; rangeIndex < ranges.Count; rangeIndex++)
                {
                    if (this.ProcessTransferred(ranges[rangeIndex], quotaRemaining))
                    {
                        send = true;
                    }
                }

                return send;
            }
        }
 public bool ProcessTransferred(SequenceRangeCollection ranges, int quotaRemaining)
 {
     if (ranges.Count == 0)
     {
         return false;
     }
     lock (this.ThisLock)
     {
         if (this.closed)
         {
             return false;
         }
         bool flag = false;
         for (int i = 0; i < ranges.Count; i++)
         {
             if (this.ProcessTransferred(ranges[i], quotaRemaining))
             {
                 flag = true;
             }
         }
         return flag;
     }
 }
        public void Merge(Int64 sequenceNumber, bool isLast)
        {
            this.ranges = this.ranges.MergeWith(sequenceNumber);

            if (isLast)
                this.last = sequenceNumber;

            if (this.AllAdded)
                this.shutdownWaitObject.Set();
        }
 public bool IsFinalAckConsistent(SequenceRangeCollection ranges)
 {
     return this.strategy.IsFinalAckConsistent(ranges);
 }
Exemplo n.º 18
0
        // February 2005 - Reads Identifier, AcknowledgementRange, Nack
        // 1.1 - Reads Identifier, AcknowledgementRange, None, Final, Nack
        internal static void ReadAck(ReliableMessagingVersion reliableMessagingVersion,
            XmlDictionaryReader reader, out UniqueId sequenceId, out SequenceRangeCollection rangeCollection,
            out bool final)
        {
            WsrmFeb2005Dictionary wsrmFeb2005Dictionary = XD.WsrmFeb2005Dictionary;
            XmlDictionaryString wsrmNs = WsrmIndex.GetNamespace(reliableMessagingVersion);

            reader.ReadStartElement(wsrmFeb2005Dictionary.SequenceAcknowledgement, wsrmNs);
            reader.ReadStartElement(wsrmFeb2005Dictionary.Identifier, wsrmNs);
            sequenceId = reader.ReadContentAsUniqueId();
            reader.ReadEndElement();
            bool allowZero = reliableMessagingVersion == ReliableMessagingVersion.WSReliableMessagingFebruary2005;

            rangeCollection = SequenceRangeCollection.Empty;
            while (reader.IsStartElement(wsrmFeb2005Dictionary.AcknowledgementRange, wsrmNs))
            {
                reader.MoveToAttribute(WsrmFeb2005Strings.Lower);
                Int64 lower = WsrmUtilities.ReadSequenceNumber(reader, allowZero);

                reader.MoveToAttribute(WsrmFeb2005Strings.Upper);
                Int64 upper = WsrmUtilities.ReadSequenceNumber(reader, allowZero);

                if (lower < 0 || lower > upper
                    || ((reliableMessagingVersion == ReliableMessagingVersion.WSReliableMessagingFebruary2005) && (lower == 0 && upper > 0))
                    || ((reliableMessagingVersion == ReliableMessagingVersion.WSReliableMessaging11) && (lower == 0)))
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                        new XmlException(SR.GetString(SR.InvalidSequenceRange, lower, upper)));
                }

                rangeCollection = rangeCollection.MergeWith(new SequenceRange(lower, upper));

                reader.MoveToElement();

                WsrmUtilities.ReadEmptyElement(reader);
            }

            bool validAck = rangeCollection.Count > 0;
            final = false;
            bool wsrm11 = reliableMessagingVersion == ReliableMessagingVersion.WSReliableMessaging11;

            if (wsrm11)
            {
                Wsrm11Dictionary wsrm11Dictionary = DXD.Wsrm11Dictionary;

                if (reader.IsStartElement(wsrm11Dictionary.None, wsrmNs))
                {
                    if (validAck)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(
                            SR.GetString(SR.UnexpectedXmlChildNode, reader.Name, reader.NodeType,
                            wsrmFeb2005Dictionary.SequenceAcknowledgement)));
                    }

                    WsrmUtilities.ReadEmptyElement(reader);
                    validAck = true;
                }

                if (reader.IsStartElement(wsrm11Dictionary.Final, wsrmNs))
                {
                    if (!validAck)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(
                            SR.GetString(SR.UnexpectedXmlChildNode, reader.Name, reader.NodeType,
                            wsrmFeb2005Dictionary.SequenceAcknowledgement)));
                    }

                    WsrmUtilities.ReadEmptyElement(reader);
                    final = true;
                }
            }

            bool foundNack = false;
            while (reader.IsStartElement(wsrmFeb2005Dictionary.Nack, wsrmNs))
            {
                if (validAck)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(
                        SR.GetString(SR.UnexpectedXmlChildNode, reader.Name, reader.NodeType,
                        MessageStrings.Body)));
                }

                reader.ReadStartElement();
                WsrmUtilities.ReadSequenceNumber(reader, true);
                reader.ReadEndElement();
                foundNack = true;
            }

            if (!validAck && !foundNack)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(
                    SR.GetString(SR.UnexpectedXmlChildNode, reader.Name, reader.NodeType,
                    MessageStrings.Body)));
            }
        }
        public void ProcessTransferred(SequenceRangeCollection ranges, int quotaRemaining)
        {
            bool invalidAck;
            bool inconsistentAck;

            this.strategy.ProcessAcknowledgement(ranges, out invalidAck, out inconsistentAck);

            if (!invalidAck && !inconsistentAck)
            {
                if (this.strategy.ProcessTransferred(ranges, quotaRemaining))
                {
                    ActionItem.Schedule(sendRetries, this);
                }
                else
                {
                    this.OnTransferComplete();
                }
            }
            else
            {
                WsrmFault fault = new InvalidAcknowledgementFault(this.id, ranges);
                RaiseFault(fault.CreateException(), fault);
            }
        }
        public bool IsFinalAckConsistent(SequenceRangeCollection ranges)
        {
            lock (this.ThisLock)
            {
                if (this.closed)
                {
                    return true;
                }

                // Nothing sent, ensure ack is empty.
                if ((this.windowStart == 1) && (this.window.Count == 0))
                {
                    return ranges.Count == 0;
                }

                // Ack is empty or first range is invalid.
                if (ranges.Count == 0 || ranges[0].Lower != 1)
                {
                    return false;
                }

                return ranges[0].Upper >= (this.windowStart - 1);
            }
        }