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); }
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); }