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