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);
        }
Ejemplo n.º 2
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);
        }