public IAsyncResult BeginSend(object registrant, Message message, Uri via, ITransportFactorySettings settings, TimeSpan timeout, AsyncCallback callback, object state, SecurityProtocol securityProtocol) { PeerFlooder localFlooder; int factoryMaxReceivedMessageSize; TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); MessageBuffer messageBuffer = null; Message securedMessage = null; ulong hopcount = PeerTransportConstants.MaxHopCount; PeerMessagePropagation propagateFlags = PeerMessagePropagation.LocalAndRemote; int messageSize = (int)-1; byte[] id; SendAsyncResult result = new SendAsyncResult(callback, state); AsyncCallback onFloodComplete = Fx.ThunkCallback(new AsyncCallback(result.OnFloodComplete)); try { lock (ThisLock) { ThrowIfNotOpen(); localFlooder = flooder; } // we know this will fit in an int because of our MaxReceivedMessageSize restrictions factoryMaxReceivedMessageSize = (int)Math.Min(maxReceivedMessageSize, settings.MaxReceivedMessageSize); Guid guid = ProcessOutgoingMessage(message, via); SecureOutgoingMessage(ref message, via, timeout, securityProtocol); if ((message is SecurityAppliedMessage)) { ArraySegment<byte> buffer = encoder.WriteMessage(message, int.MaxValue, bufferManager); securedMessage = encoder.ReadMessage(buffer, bufferManager); id = (message as SecurityAppliedMessage).PrimarySignatureValue; messageSize = (int)buffer.Count; } else { securedMessage = message; id = guid.ToByteArray(); } messageBuffer = securedMessage.CreateBufferedCopy(factoryMaxReceivedMessageSize); string contentType = settings.MessageEncoderFactory.Encoder.ContentType; if (this.messagePropagationFilter != null) { using (Message filterMessage = messageBuffer.CreateMessage()) { propagateFlags = ((IPeerNodeMessageHandling)this).DetermineMessagePropagation(filterMessage, PeerMessageOrigination.Local); } } if ((propagateFlags & PeerMessagePropagation.Remote) != PeerMessagePropagation.None) { if (hopcount == 0) propagateFlags &= ~PeerMessagePropagation.Remote; } // flood it out IAsyncResult ar = null; if ((propagateFlags & PeerMessagePropagation.Remote) != 0) { ar = localFlooder.BeginFloodEncodedMessage(id, messageBuffer, timeoutHelper.RemainingTime(), onFloodComplete, null); if (DiagnosticUtility.ShouldTraceVerbose) { TraceUtility.TraceEvent(TraceEventType.Verbose, TraceCode.PeerChannelMessageSent, SR.GetString(SR.TraceCodePeerChannelMessageSent), this, message); } } else { ar = new CompletedAsyncResult(onFloodComplete, null); } if (ar == null) { Fx.Assert("SendAsyncResult must have an Async Result for onFloodComplete"); } // queue up the pre-encoded message for local channels if ((propagateFlags & PeerMessagePropagation.Local) != 0) { using (Message msg = messageBuffer.CreateMessage()) { int i = msg.Headers.FindHeader(SecurityJan2004Strings.Security, SecurityJan2004Strings.Namespace); if (i >= 0) { msg.Headers.AddUnderstood(i); } using (MessageBuffer clientBuffer = msg.CreateBufferedCopy(factoryMaxReceivedMessageSize)) { DeliverMessageToClientChannels(registrant, clientBuffer, via, message.Headers.To, contentType, messageSize, -1, null); } } } result.OnLocalDispatchComplete(result); } finally { message.Close(); if (securedMessage != null) securedMessage.Close(); if (messageBuffer != null) messageBuffer.Close(); } return result; }
public IAsyncResult BeginSend(object registrant, Message message, Uri via, ITransportFactorySettings settings, TimeSpan timeout, AsyncCallback callback, object state, SecurityProtocol securityProtocol) { TimeoutHelper helper = new TimeoutHelper(timeout); MessageBuffer encodedMessage = null; Message message2 = null; ulong maxValue = ulong.MaxValue; PeerMessagePropagation localAndRemote = PeerMessagePropagation.LocalAndRemote; int messageSize = -1; SendAsyncResult result = new SendAsyncResult(callback, state); AsyncCallback callback2 = Fx.ThunkCallback(new AsyncCallback(result.OnFloodComplete)); try { PeerFlooder flooder; byte[] primarySignatureValue; lock (this.ThisLock) { this.ThrowIfNotOpen(); flooder = this.flooder; } int maxBufferSize = (int) Math.Min(this.maxReceivedMessageSize, settings.MaxReceivedMessageSize); Guid guid = this.ProcessOutgoingMessage(message, via); this.SecureOutgoingMessage(ref message, via, timeout, securityProtocol); if (message is SecurityAppliedMessage) { ArraySegment<byte> buffer = this.encoder.WriteMessage(message, 0x7fffffff, this.bufferManager); message2 = this.encoder.ReadMessage(buffer, this.bufferManager); primarySignatureValue = (message as SecurityAppliedMessage).PrimarySignatureValue; messageSize = buffer.Count; } else { message2 = message; primarySignatureValue = guid.ToByteArray(); } encodedMessage = message2.CreateBufferedCopy(maxBufferSize); string contentType = settings.MessageEncoderFactory.Encoder.ContentType; if (this.messagePropagationFilter != null) { using (Message message3 = encodedMessage.CreateMessage()) { localAndRemote = ((IPeerNodeMessageHandling) this).DetermineMessagePropagation(message3, PeerMessageOrigination.Local); } } if (((localAndRemote & PeerMessagePropagation.Remote) != PeerMessagePropagation.None) && (maxValue == 0L)) { localAndRemote &= ~PeerMessagePropagation.Remote; } IAsyncResult result2 = null; if ((localAndRemote & PeerMessagePropagation.Remote) != PeerMessagePropagation.None) { result2 = flooder.BeginFloodEncodedMessage(primarySignatureValue, encodedMessage, helper.RemainingTime(), callback2, null); if (System.ServiceModel.DiagnosticUtility.ShouldTraceVerbose) { TraceUtility.TraceEvent(TraceEventType.Verbose, 0x4003e, System.ServiceModel.SR.GetString("TraceCodePeerChannelMessageSent"), this, message); } } else { result2 = new CompletedAsyncResult(callback2, null); } if ((localAndRemote & PeerMessagePropagation.Local) != PeerMessagePropagation.None) { using (Message message4 = encodedMessage.CreateMessage()) { int i = message4.Headers.FindHeader("Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"); if (i >= 0) { message4.Headers.AddUnderstood(i); } using (MessageBuffer buffer3 = message4.CreateBufferedCopy(maxBufferSize)) { this.DeliverMessageToClientChannels(registrant, buffer3, via, message.Headers.To, contentType, messageSize, -1, null); } } } result.OnLocalDispatchComplete(result); } finally { message.Close(); if (message2 != null) { message2.Close(); } if (encodedMessage != null) { encodedMessage.Close(); } } return result; }