Example #1
0
        /// <summary>
        /// Returns whether or not a message received on a peer channel should be propagated, and if so, the destination of the message.
        /// </summary>
        /// <param name="message">The message to evaluate for propagation.</param>
        /// <param name="origination">A <see cref="T:System.ServiceModel.PeerMessageOrigination"/> enumeration value that specifies the origin (local or remote) of the message under evaluation.</param>
        /// <returns>
        /// A <see cref="T:System.ServiceModel.PeerMessagePropagation"/> enumeration value that indicates the destination of the message (local, remote, both, or no propagation at all).
        /// </returns>
        public override PeerMessagePropagation ShouldMessagePropagate(Message message, PeerMessageOrigination origination)
        {
            PeerMessagePropagation destination = PeerMessagePropagation.LocalAndRemote;

            if (origination == PeerMessageOrigination.Local)
            {
                destination = PeerMessagePropagation.Remote;
            }
            return(destination);
        }
        void IPeerNodeMessageHandling.HandleIncomingMessage(MessageBuffer messageBuffer, PeerMessagePropagation propagateFlags,
            int index, MessageHeader hopHeader, Uri via, Uri to)
        {
            if (DiagnosticUtility.ShouldTraceVerbose)
            {
                TraceUtility.TraceEvent(TraceEventType.Verbose, TraceCode.PeerFloodedMessageReceived, SR.GetString(SR.TraceCodePeerFloodedMessageReceived), this.traceRecord, this, null);
            }

            if (via == null)
            {
                Fx.Assert("No VIA in the forwarded message!");
                using (Message message = messageBuffer.CreateMessage())
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.PeerMessageMustHaveVia, message.Headers.Action)));
                }
            }
            if ((propagateFlags & PeerMessagePropagation.Local) != 0)
            {
                DeliverMessageToClientChannels(null, messageBuffer, via, to, messageBuffer.MessageContentType, (int)maxReceivedMessageSize, index, hopHeader);
                messageBuffer = null;
            }
            else
            {
                if (DiagnosticUtility.ShouldTraceVerbose)
                {
                    using (Message traceMessage = messageBuffer.CreateMessage())
                    {
                        TraceUtility.TraceEvent(TraceEventType.Verbose, TraceCode.PeerFloodedMessageNotPropagated, SR.GetString(SR.TraceCodePeerFloodedMessageNotPropagated), this.traceRecord, this, null, traceMessage);
                    }
                }
            }
        }
        public virtual IAsyncResult OnFloodedMessage(IPeerNeighbor neighbor, TFloodContract floodInfo, AsyncCallback callback, object state)
        {
            bool                useful        = false;
            MessageBuffer       messageBuffer = null;
            Message             message       = null;
            int                 index         = 0;
            ulong               maxValue      = ulong.MaxValue;
            MessageHeader       hopHeader     = null;
            bool                flag2         = false;
            PeerMessageProperty property      = null;
            IAsyncResult        result        = null;

            try
            {
                property = (PeerMessageProperty)floodInfo.Properties["PeerProperty"];
                if (!property.MessageVerified)
                {
                    if (property.CacheMiss > 2)
                    {
                        UtilityExtension.ReportCacheMiss(neighbor, property.CacheMiss);
                    }
                    result = new CompletedAsyncResult(callback, state);
                }
                else
                {
                    useful        = true;
                    messageBuffer = floodInfo.CreateBufferedCopy((int)this.config.MaxReceivedMessageSize);
                    message       = messageBuffer.CreateMessage();
                    Uri peerVia = property.PeerVia;
                    Uri peerTo  = property.PeerTo;
                    message.Headers.To = message.Properties.Via = peerVia;
                    index = this.UpdateHopCount(message, out hopHeader, out maxValue);
                    PeerMessagePropagation localAndRemote = PeerMessagePropagation.LocalAndRemote;
                    if (property.SkipLocalChannels)
                    {
                        localAndRemote = PeerMessagePropagation.Remote;
                    }
                    else if (this.messageHandler.HasMessagePropagation)
                    {
                        using (Message message2 = messageBuffer.CreateMessage())
                        {
                            localAndRemote = this.messageHandler.DetermineMessagePropagation(message2, PeerMessageOrigination.Remote);
                        }
                    }
                    if (((localAndRemote & PeerMessagePropagation.Remote) != PeerMessagePropagation.None) && (maxValue == 0L))
                    {
                        localAndRemote &= ~PeerMessagePropagation.Remote;
                    }
                    if ((localAndRemote & PeerMessagePropagation.Remote) != PeerMessagePropagation.None)
                    {
                        result = this.BeginFloodReceivedMessage(neighbor, messageBuffer, PeerTransportConstants.ForwardTimeout, callback, state, index, hopHeader);
                    }
                    else
                    {
                        result = new CompletedAsyncResult(callback, state);
                    }
                    if ((localAndRemote & PeerMessagePropagation.Local) != PeerMessagePropagation.None)
                    {
                        this.messageHandler.HandleIncomingMessage(messageBuffer, localAndRemote, index, hopHeader, peerVia, peerTo);
                    }
                }
                UtilityExtension.UpdateLinkUtility(neighbor, useful);
            }
            catch (Exception exception)
            {
                if (Fx.IsFatal(exception))
                {
                    flag2 = true;
                    throw;
                }
                if (PeerFlooderBase <TFloodContract, TLinkContract> .CloseNeighborIfKnownException(this.neighborManager, exception, neighbor) != null)
                {
                    throw;
                }
                System.ServiceModel.DiagnosticUtility.ExceptionUtility.TraceHandledException(exception, TraceEventType.Information);
            }
            finally
            {
                if (!flag2)
                {
                    if (message != null)
                    {
                        message.Close();
                    }
                    if (messageBuffer != null)
                    {
                        messageBuffer.Close();
                    }
                }
            }
            return(result);
        }
Example #4
0
        public virtual IAsyncResult OnFloodedMessage(IPeerNeighbor neighbor, TFloodContract floodInfo, AsyncCallback callback, object state)
        {
            bool                process       = false;
            MessageBuffer       messageBuffer = null;
            Message             message       = null;
            Uri                 via;
            Uri                 to;
            int                 index         = 0;
            ulong               remainingHops = PeerTransportConstants.MaxHopCount;
            MessageHeader       hopHeader     = null;
            bool                fatal         = false;
            PeerMessageProperty peerProperty  = null;
            IAsyncResult        result        = null;

            try
            {
                peerProperty = (PeerMessageProperty)floodInfo.Properties[PeerStrings.PeerProperty];
                if (!peerProperty.MessageVerified)
                {
                    if (peerProperty.CacheMiss > UtilityExtension.AcceptableMissDistance)
                    {
                        UtilityExtension.ReportCacheMiss(neighbor, peerProperty.CacheMiss);
                    }
                    result = new CompletedAsyncResult(callback, state);
                }
                else
                {
                    process            = true;
                    messageBuffer      = floodInfo.CreateBufferedCopy((int)this.config.MaxReceivedMessageSize);
                    message            = messageBuffer.CreateMessage();
                    via                = peerProperty.PeerVia;
                    to                 = peerProperty.PeerTo;
                    message.Headers.To = message.Properties.Via = via;

                    index = UpdateHopCount(message, out hopHeader, out remainingHops);

                    PeerMessagePropagation propagateFlags = PeerMessagePropagation.LocalAndRemote;
                    if (peerProperty.SkipLocalChannels)
                    {
                        propagateFlags = PeerMessagePropagation.Remote;
                    }
                    else if (messageHandler.HasMessagePropagation)
                    {
                        using (Message filterMessage = messageBuffer.CreateMessage())
                        {
                            propagateFlags = messageHandler.DetermineMessagePropagation(filterMessage, PeerMessageOrigination.Remote);
                        }
                    }

                    if ((propagateFlags & PeerMessagePropagation.Remote) != 0)
                    {
                        if (remainingHops == 0)
                        {
                            propagateFlags &= ~PeerMessagePropagation.Remote;
                        }
                    }
                    if ((propagateFlags & PeerMessagePropagation.Remote) != 0)
                    {
                        result = BeginFloodReceivedMessage(neighbor, messageBuffer, PeerTransportConstants.ForwardTimeout, callback, state, index, hopHeader);
                    }
                    else
                    {
                        result = new CompletedAsyncResult(callback, state);
                    }
                    if ((propagateFlags & PeerMessagePropagation.Local) != 0)
                    {
                        messageHandler.HandleIncomingMessage(messageBuffer, propagateFlags, index, hopHeader, via, to);
                    }
                }
                UtilityExtension.UpdateLinkUtility(neighbor, process);
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    fatal = true;
                    throw;
                }
                if (null != CloseNeighborIfKnownException(neighborManager, e, neighbor))
                {
                    throw;
                }
                DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
            }
            finally
            {
                if (!fatal)
                {
                    if (message != null)
                    {
                        message.Close();
                    }
                    if (messageBuffer != null)
                    {
                        messageBuffer.Close();
                    }
                }
            }
            return(result);
        }
 void IPeerNodeMessageHandling.HandleIncomingMessage(MessageBuffer messageBuffer, PeerMessagePropagation propagateFlags, int index, MessageHeader hopHeader, Uri via, Uri to)
 {
     if (System.ServiceModel.DiagnosticUtility.ShouldTraceVerbose)
     {
         TraceUtility.TraceEvent(TraceEventType.Verbose, 0x40045, System.ServiceModel.SR.GetString("TraceCodePeerFloodedMessageReceived"), this.traceRecord, this, null);
     }
     if (via == null)
     {
         using (Message message = messageBuffer.CreateMessage())
         {
             throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(System.ServiceModel.SR.GetString("PeerMessageMustHaveVia", new object[] { message.Headers.Action })));
         }
     }
     if ((propagateFlags & PeerMessagePropagation.Local) != PeerMessagePropagation.None)
     {
         this.DeliverMessageToClientChannels(null, messageBuffer, via, to, messageBuffer.MessageContentType, (int) this.maxReceivedMessageSize, index, hopHeader);
         messageBuffer = null;
     }
     else if (System.ServiceModel.DiagnosticUtility.ShouldTraceVerbose)
     {
         using (Message message2 = messageBuffer.CreateMessage())
         {
             TraceUtility.TraceEvent(TraceEventType.Verbose, 0x40046, System.ServiceModel.SR.GetString("TraceCodePeerFloodedMessageNotPropagated"), this.traceRecord, this, null, message2);
         }
     }
 }