예제 #1
0
        public static PeerFlooder CreateFlooder(PeerNodeConfig config, PeerNeighborManager neighborManager, IPeerNodeMessageHandling messageHandler)
        {
            PeerFlooder flooder = new PeerFlooder(config, neighborManager);

            flooder.messageHandler = messageHandler;
            return(flooder);
        }
예제 #2
0
 public PeerMaintainerBase(PeerNodeConfig config, PeerNeighborManager neighborManager, PeerFlooder flooder)
 {
     this.neighborManager = neighborManager;
     this.flooder         = flooder;
     this.config          = config;
     this.thisLock        = new object();
     this.referralCache   = new Dictionary <EndpointAddress, Referral>();
     this.maintainerTimer = new IOThreadTimer(new Action <object>(this.OnMaintainerTimer), this, false);
 }
        void CloseCore(TimeSpan timeout, bool graceful)
        {
            PeerService lclService;
            PeerMaintainer lclMaintainer;
            PeerNeighborManager lclNeighborManager;
            PeerConnector lclConnector;
            PeerIPHelper lclIPHelper;
            PeerNodeConfig lclConfig;
            PeerFlooder lclFlooder;
            Exception exception = null;

            TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
            if (DiagnosticUtility.ShouldTraceInformation)
            {
                TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.PeerNodeClosing, SR.GetString(SR.TraceCodePeerNodeClosing), this.traceRecord, this, null);
            }

            lock (ThisLock)
            {
                isOpen = false;
                lclMaintainer = maintainer;
                lclNeighborManager = neighborManager;
                lclConnector = connector;
                lclIPHelper = ipHelper;
                lclService = service;
                lclConfig = config;
                lclFlooder = flooder;
            }

            // only unregister if we are doing a g----ful shutdown
            try
            {
                if (graceful)
                {
                    UnregisterAddress(timeout);
                }
                else
                {
                    if (lclConfig != null)
                    {
                        ActionItem.Schedule(new Action<object>(UnregisterAddress), lclConfig.UnregisterTimeout);
                    }
                }
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e)) throw;
                DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
                if (exception == null) exception = e;
            }

            try
            {
                if (lclConnector != null)
                    lclConnector.Closing();

                if (lclService != null)
                {
                    try
                    {
                        lclService.Abort();
                    }
                    catch (Exception e)
                    {
                        if (Fx.IsFatal(e)) throw;
                        DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
                        if (exception == null) exception = e;
                    }
                }

                if (lclMaintainer != null)
                {
                    try
                    {
                        lclMaintainer.Close();
                    }
                    catch (Exception e)
                    {
                        if (Fx.IsFatal(e)) throw;
                        DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
                        if (exception == null) exception = e;
                    }
                }

                if (lclIPHelper != null)
                {
                    try
                    {
                        lclIPHelper.Close();
                        lclIPHelper.AddressChanged -= new EventHandler(stateManager.OnIPAddressesChanged);
                    }
                    catch (Exception e)
                    {
                        if (Fx.IsFatal(e)) throw;
                        DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
                        if (exception == null) exception = e;
                    }
                }
                if (lclNeighborManager != null)
                {
                    lclNeighborManager.NeighborConnected -= new EventHandler(OnNeighborConnected);
                    lclNeighborManager.NeighborOpened -= new EventHandler(this.securityManager.OnNeighborOpened);
                    this.securityManager.OnNeighborAuthenticated -= new EventHandler(this.OnNeighborAuthenticated);
                    lclNeighborManager.Online -= new EventHandler(FireOnline);
                    lclNeighborManager.Offline -= new EventHandler(FireOffline);
                    try
                    {
                        lclNeighborManager.Shutdown(graceful, timeoutHelper.RemainingTime());
                    }
                    catch (Exception e)
                    {
                        if (Fx.IsFatal(e)) throw;
                        DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
                        if (exception == null) exception = e;
                    }

                    // unregister for neighbor close events once shutdown has completed
                    lclNeighborManager.NeighborClosed -= new EventHandler<PeerNeighborCloseEventArgs>(OnNeighborClosed);
                    lclNeighborManager.NeighborClosing -= new EventHandler<PeerNeighborCloseEventArgs>(OnNeighborClosing);
                    lclNeighborManager.Close();
                }

                if (lclConnector != null)
                {
                    try
                    {
                        lclConnector.Close();
                    }
                    catch (Exception e)
                    {
                        if (Fx.IsFatal(e)) throw;
                        DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
                        if (exception == null) exception = e;
                    }
                }

                if (lclFlooder != null)
                {
                    try
                    {
                        lclFlooder.Close();
                    }
                    catch (Exception e)
                    {
                        if (Fx.IsFatal(e)) throw;
                        DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
                        if (exception == null) exception = e;
                    }
                }

            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e)) throw;
                if (exception == null) exception = e;
            }

            // reset object for next call to open
            EventHandler abortedHandler = null;
            lock (ThisLock)
            {
                // clear out old components (so they can be garbage collected)
                neighborManager = null;
                connector = null;
                maintainer = null;
                flooder = null;
                ipHelper = null;
                service = null;

                // reset generated config
                config = null;
                meshId = null;
                abortedHandler = Aborted;
            }

            // Notify anyone who is interested that abort has occured 
            if (!graceful && abortedHandler != null)
            {
                try
                {
                    abortedHandler(this, EventArgs.Empty);
                }
                catch (Exception e)
                {
                    if (Fx.IsFatal(e)) throw;
                    DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
                    if (exception == null) exception = e;
                }
            }

            if (DiagnosticUtility.ShouldTraceInformation)
            {
                TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.PeerNodeClosed, SR.GetString(SR.TraceCodePeerNodeClosed), this.traceRecord, this, null);
            }
            if (exception != null && graceful == true)                          // Swallows all non fatal exceptions during Abort
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(exception);
            }
        }
        // the core functionality of open (all but waiting for a connection)
        void OpenCore(TimeSpan timeout)
        {
            TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
            PeerMaintainer lclMaintainer;
            PeerNodeConfig lclConfig;
            string lclMeshId;

            lock (ThisLock)
            {
                if (ListenUri == null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ListenUriNotSet, this.GetType())));
                }

                // extract mesh id from listen uri
                meshId = ListenUri.Host;

                // generate the node id
                byte[] bytes = new byte[sizeof(ulong)];
                ulong nodeId = 0;
                do
                {
                    System.ServiceModel.Security.CryptoHelper.FillRandomBytes(bytes);
                    for (int i = 0; i < sizeof(ulong); i++)
                        nodeId |= ((ulong)bytes[i]) << i * 8;
                }
                while (nodeId == PeerTransportConstants.InvalidNodeId);

                // now that the node id has been generated, create the trace record that describes this
                traceRecord = new PeerNodeTraceRecord(nodeId, meshId);
                if (DiagnosticUtility.ShouldTraceInformation)
                {
                    TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.PeerNodeOpening, SR.GetString(SR.TraceCodePeerNodeOpening), this.traceRecord, this, null);
                }

                // create the node configuration
                config = new PeerNodeConfig(meshId,
                                                nodeId,
                                                resolver,
                                                messagePropagationFilter,
                                                encoder,
                                                ListenUri, listenIPAddress, port,
                                                maxReceivedMessageSize, minNeighbors, idealNeighbors, maxNeighbors, maxReferrals,
                                                connectTimeout, maintainerInterval,
                                                securityManager,
                                                this.readerQuotas,
                                                this.maxBufferPoolSize,
                                                this.MaxSendQueue,
                                                this.MaxReceiveQueue);

                // create components
                if (listenIPAddress != null)
                    ipHelper = new PeerIPHelper(listenIPAddress);
                else
                    ipHelper = new PeerIPHelper();
                bufferManager = BufferManager.CreateBufferManager(64 * config.MaxReceivedMessageSize, (int)config.MaxReceivedMessageSize);
                neighborManager = new PeerNeighborManager(ipHelper,
                                                            config,
                                                            this);
                flooder = PeerFlooder.CreateFlooder(config, neighborManager, this);
                maintainer = new PeerMaintainer(config, neighborManager, flooder);
                connector = new PeerConnector(config, neighborManager, maintainer);

                Dictionary<Type, object> services = serviceHandlers;
                if (services == null)
                {
                    services = new Dictionary<Type, object>();
                    services.Add(typeof(IPeerConnectorContract), connector);
                    services.Add(typeof(IPeerFlooderContract<Message, UtilityInfo>), flooder);
                }
                service = new PeerService(this.config,
                                        neighborManager.ProcessIncomingChannel,
                                        neighborManager.GetNeighborFromProxy,
                                        services,
                                        this);
                this.securityManager.MeshId = this.meshId;
                service.Open(timeoutHelper.RemainingTime());

                // register for events
                neighborManager.NeighborClosed += new EventHandler<PeerNeighborCloseEventArgs>(OnNeighborClosed);
                neighborManager.NeighborClosing += new EventHandler<PeerNeighborCloseEventArgs>(OnNeighborClosing);
                neighborManager.NeighborConnected += new EventHandler(OnNeighborConnected);
                neighborManager.NeighborOpened += new EventHandler(this.SecurityManager.OnNeighborOpened);
                this.securityManager.OnNeighborAuthenticated += new EventHandler(this.OnNeighborAuthenticated);
                neighborManager.Online += new EventHandler(FireOnline);
                neighborManager.Offline += new EventHandler(FireOffline);
                ipHelper.AddressChanged += new EventHandler(stateManager.OnIPAddressesChanged);

                // open components
                ipHelper.Open();

                // Set the listen address before opening any more components
                PeerNodeAddress nodeAddress = new PeerNodeAddress(service.GetListenAddress(), ipHelper.GetLocalAddresses());
                config.SetListenAddress(nodeAddress);

                neighborManager.Open(service.Binding, service);
                connector.Open();
                maintainer.Open();
                flooder.Open();

                isOpen = true;
                completeTraceRecord = new PeerNodeTraceRecord(nodeId, meshId, nodeAddress);

                // Set these locals inside the lock (Abort may occur whilst Opening)
                lclMaintainer = maintainer;

                lclMeshId = meshId;
                lclConfig = config;
                openException = null;

            }

            // retrieve listen addresses and register with the resolver
            if (isOpen)
            {
                // attempt to connect to the mesh
                lclMaintainer.ScheduleConnect(new PeerMaintainer.ConnectCallback(OnConnectionAttemptCompleted));
            }
        }
예제 #5
0
 public PeerMaintainer(PeerNodeConfig config, PeerNeighborManager neighborManager, PeerFlooder flooder) : base(config, neighborManager, flooder)
 {
 }
예제 #6
0
        //this is the callback routine for async completion on channel BeginSend() operations.
        //if we are done, simply return. This can happen if user called sync EndX.
        //if the flooder is still processing BeginSend(), then we probably cant complete. In this case, add the result to pending and return
        //main thread will flush the pending completions in MarkEnd().
        //otherwise, call EndX on the result and remove it from results.
        //if this is the last invoke, signal user using base.Complete AND isCompleted=true
        internal void OnSendComplete(IAsyncResult result)
        {
            bool          callComplete = false;
            IPeerNeighbor neighbor     = null;
            bool          fatal        = false;

            if (isCompleted)
            {
                return;
            }
            Message message = (Message)result.AsyncState;

            //wait until flooder had a chance to call all outgoing channels and give us Async results.
            lock (ThisLock)
            {
                if (isCompleted)
                {
                    return;
                }

                if (!this.results.TryGetValue(result, out neighbor))
                {
                    if (!doneAdding)
                    {
                        this.pending.Add(result);
                    }
                    else
                    {
                        throw Fx.AssertAndThrow("IAsyncResult is un-accounted for.");
                    }
                    return;
                }
                this.results.Remove(result);

                try
                {
                    //try doing this only if the async result is marked !CompletedSynchronously.
                    if (!result.CompletedSynchronously)
                    {
                        neighbor.EndSend(result);
                        offNode = true;
                        UtilityExtension.OnEndSend(neighbor, this);
                    }
                }
                catch (Exception e)
                {
                    if (Fx.IsFatal(e))
                    {
                        fatal = true;
                        throw;
                    }

                    Exception temp = PeerFlooder.CloseNeighborIfKnownException(pnm, e, neighbor);
                    //we want to return the very first exception to the user.
                    if (temp != null && this.doneAdding && !this.shouldCallComplete)
                    {
                        throw;
                    }
                    if (this.exception == null)
                    {
                        this.exception = temp;
                    }
                    DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
                }
                finally
                {
                    if (message != null && !result.CompletedSynchronously && !fatal)
                    {
                        message.Close();
                    }
                }
                //dont want to call Complete from the lock.
                //we just decide if this thread should call complete and call outside the lock.
                if (this.results.Count == 0 && this.doneAdding && this.shouldCallComplete)
                {
                    this.isCompleted = true;
                    callComplete     = true;
                }
            }
            //if we are done with callbacks and beginx calls,
            if (callComplete && this.shouldCallComplete)
            {
                CompleteOp(false);
            }
        }
 private void OpenCore(TimeSpan timeout)
 {
     PeerMaintainer maintainer;
     TimeoutHelper helper = new TimeoutHelper(timeout);
     lock (this.ThisLock)
     {
         if (this.ListenUri == null)
         {
             throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(System.ServiceModel.SR.GetString("ListenUriNotSet", new object[] { base.GetType() })));
         }
         this.meshId = this.ListenUri.Host;
         byte[] buffer = new byte[8];
         ulong id = 0L;
         do
         {
             CryptoHelper.FillRandomBytes(buffer);
             for (int i = 0; i < 8; i++)
             {
                 id |= buffer[i] << (i * 8);
             }
         }
         while (id == 0L);
         this.traceRecord = new PeerNodeTraceRecord(id, this.meshId);
         if (System.ServiceModel.DiagnosticUtility.ShouldTraceInformation)
         {
             TraceUtility.TraceEvent(TraceEventType.Information, 0x40040, System.ServiceModel.SR.GetString("TraceCodePeerNodeOpening"), this.traceRecord, this, null);
         }
         this.config = new PeerNodeConfig(this.meshId, id, this.resolver, this.messagePropagationFilter, this.encoder, this.ListenUri, this.listenIPAddress, this.port, this.maxReceivedMessageSize, this.minNeighbors, this.idealNeighbors, this.maxNeighbors, this.maxReferrals, this.connectTimeout, this.maintainerInterval, this.securityManager, this.readerQuotas, this.maxBufferPoolSize, this.MaxSendQueue, this.MaxReceiveQueue);
         if (this.listenIPAddress != null)
         {
             this.ipHelper = new PeerIPHelper(this.listenIPAddress);
         }
         else
         {
             this.ipHelper = new PeerIPHelper();
         }
         this.bufferManager = BufferManager.CreateBufferManager(0x40L * this.config.MaxReceivedMessageSize, (int) this.config.MaxReceivedMessageSize);
         this.neighborManager = new PeerNeighborManager(this.ipHelper, this.config, this);
         this.flooder = PeerFlooder.CreateFlooder(this.config, this.neighborManager, this);
         this.maintainer = new PeerMaintainer(this.config, this.neighborManager, this.flooder);
         this.connector = new PeerConnector(this.config, this.neighborManager, this.maintainer);
         Dictionary<System.Type, object> serviceHandlers = this.serviceHandlers;
         if (serviceHandlers == null)
         {
             serviceHandlers = new Dictionary<System.Type, object>();
             serviceHandlers.Add(typeof(IPeerConnectorContract), this.connector);
             serviceHandlers.Add(typeof(IPeerFlooderContract<Message, UtilityInfo>), this.flooder);
         }
         this.service = new PeerService(this.config, new PeerService.ChannelCallback(this.neighborManager.ProcessIncomingChannel), new PeerService.GetNeighborCallback(this.neighborManager.GetNeighborFromProxy), serviceHandlers, this);
         this.securityManager.MeshId = this.meshId;
         this.service.Open(helper.RemainingTime());
         this.neighborManager.NeighborClosed += new EventHandler<PeerNeighborCloseEventArgs>(this.OnNeighborClosed);
         this.neighborManager.NeighborClosing += new EventHandler<PeerNeighborCloseEventArgs>(this.OnNeighborClosing);
         this.neighborManager.NeighborConnected += new EventHandler(this.OnNeighborConnected);
         this.neighborManager.NeighborOpened += new EventHandler(this.SecurityManager.OnNeighborOpened);
         this.securityManager.OnNeighborAuthenticated = (EventHandler) Delegate.Combine(this.securityManager.OnNeighborAuthenticated, new EventHandler(this.OnNeighborAuthenticated));
         this.neighborManager.Online += new EventHandler(this.FireOnline);
         this.neighborManager.Offline += new EventHandler(this.FireOffline);
         this.ipHelper.AddressChanged += new EventHandler(this.stateManager.OnIPAddressesChanged);
         this.ipHelper.Open();
         PeerNodeAddress address = new PeerNodeAddress(this.service.GetListenAddress(), this.ipHelper.GetLocalAddresses());
         this.config.SetListenAddress(address);
         this.neighborManager.Open(this.service.Binding, this.service);
         this.connector.Open();
         this.maintainer.Open();
         this.flooder.Open();
         this.isOpen = true;
         this.completeTraceRecord = new PeerNodeTraceRecord(id, this.meshId, address);
         maintainer = this.maintainer;
         this.openException = null;
     }
     if (this.isOpen)
     {
         maintainer.ScheduleConnect(new PeerMaintainerBase<ConnectAlgorithms>.ConnectCallback(this.OnConnectionAttemptCompleted));
     }
 }
 private void CloseCore(TimeSpan timeout, bool graceful)
 {
     PeerService service;
     PeerMaintainer maintainer;
     PeerNeighborManager neighborManager;
     PeerConnector connector;
     PeerIPHelper ipHelper;
     PeerNodeConfig config;
     PeerFlooder flooder;
     Exception exception = null;
     TimeoutHelper helper2 = new TimeoutHelper(timeout);
     if (System.ServiceModel.DiagnosticUtility.ShouldTraceInformation)
     {
         TraceUtility.TraceEvent(TraceEventType.Information, 0x40043, System.ServiceModel.SR.GetString("TraceCodePeerNodeClosing"), this.traceRecord, this, null);
     }
     lock (this.ThisLock)
     {
         this.isOpen = false;
         maintainer = this.maintainer;
         neighborManager = this.neighborManager;
         connector = this.connector;
         ipHelper = this.ipHelper;
         service = this.service;
         config = this.config;
         flooder = this.flooder;
     }
     try
     {
         if (graceful)
         {
             this.UnregisterAddress(timeout);
         }
         else if (config != null)
         {
             ActionItem.Schedule(new Action<object>(this.UnregisterAddress), config.UnregisterTimeout);
         }
     }
     catch (Exception exception2)
     {
         if (Fx.IsFatal(exception2))
         {
             throw;
         }
         System.ServiceModel.DiagnosticUtility.ExceptionUtility.TraceHandledException(exception2, TraceEventType.Information);
         if (exception == null)
         {
             exception = exception2;
         }
     }
     try
     {
         if (connector != null)
         {
             connector.Closing();
         }
         if (service != null)
         {
             try
             {
                 service.Abort();
             }
             catch (Exception exception3)
             {
                 if (Fx.IsFatal(exception3))
                 {
                     throw;
                 }
                 System.ServiceModel.DiagnosticUtility.ExceptionUtility.TraceHandledException(exception3, TraceEventType.Information);
                 if (exception == null)
                 {
                     exception = exception3;
                 }
             }
         }
         if (maintainer != null)
         {
             try
             {
                 maintainer.Close();
             }
             catch (Exception exception4)
             {
                 if (Fx.IsFatal(exception4))
                 {
                     throw;
                 }
                 System.ServiceModel.DiagnosticUtility.ExceptionUtility.TraceHandledException(exception4, TraceEventType.Information);
                 if (exception == null)
                 {
                     exception = exception4;
                 }
             }
         }
         if (ipHelper != null)
         {
             try
             {
                 ipHelper.Close();
                 ipHelper.AddressChanged -= new EventHandler(this.stateManager.OnIPAddressesChanged);
             }
             catch (Exception exception5)
             {
                 if (Fx.IsFatal(exception5))
                 {
                     throw;
                 }
                 System.ServiceModel.DiagnosticUtility.ExceptionUtility.TraceHandledException(exception5, TraceEventType.Information);
                 if (exception == null)
                 {
                     exception = exception5;
                 }
             }
         }
         if (neighborManager != null)
         {
             neighborManager.NeighborConnected -= new EventHandler(this.OnNeighborConnected);
             neighborManager.NeighborOpened -= new EventHandler(this.securityManager.OnNeighborOpened);
             this.securityManager.OnNeighborAuthenticated = (EventHandler) Delegate.Remove(this.securityManager.OnNeighborAuthenticated, new EventHandler(this.OnNeighborAuthenticated));
             neighborManager.Online -= new EventHandler(this.FireOnline);
             neighborManager.Offline -= new EventHandler(this.FireOffline);
             try
             {
                 neighborManager.Shutdown(graceful, helper2.RemainingTime());
             }
             catch (Exception exception6)
             {
                 if (Fx.IsFatal(exception6))
                 {
                     throw;
                 }
                 System.ServiceModel.DiagnosticUtility.ExceptionUtility.TraceHandledException(exception6, TraceEventType.Information);
                 if (exception == null)
                 {
                     exception = exception6;
                 }
             }
             neighborManager.NeighborClosed -= new EventHandler<PeerNeighborCloseEventArgs>(this.OnNeighborClosed);
             neighborManager.NeighborClosing -= new EventHandler<PeerNeighborCloseEventArgs>(this.OnNeighborClosing);
             neighborManager.Close();
         }
         if (connector != null)
         {
             try
             {
                 connector.Close();
             }
             catch (Exception exception7)
             {
                 if (Fx.IsFatal(exception7))
                 {
                     throw;
                 }
                 System.ServiceModel.DiagnosticUtility.ExceptionUtility.TraceHandledException(exception7, TraceEventType.Information);
                 if (exception == null)
                 {
                     exception = exception7;
                 }
             }
         }
         if (flooder != null)
         {
             try
             {
                 flooder.Close();
             }
             catch (Exception exception8)
             {
                 if (Fx.IsFatal(exception8))
                 {
                     throw;
                 }
                 System.ServiceModel.DiagnosticUtility.ExceptionUtility.TraceHandledException(exception8, TraceEventType.Information);
                 if (exception == null)
                 {
                     exception = exception8;
                 }
             }
         }
     }
     catch (Exception exception9)
     {
         if (Fx.IsFatal(exception9))
         {
             throw;
         }
         if (exception == null)
         {
             exception = exception9;
         }
     }
     EventHandler aborted = null;
     lock (this.ThisLock)
     {
         this.neighborManager = null;
         this.connector = null;
         this.maintainer = null;
         this.flooder = null;
         this.ipHelper = null;
         this.service = null;
         this.config = null;
         this.meshId = null;
         aborted = this.Aborted;
     }
     if (!graceful && (aborted != null))
     {
         try
         {
             aborted(this, EventArgs.Empty);
         }
         catch (Exception exception10)
         {
             if (Fx.IsFatal(exception10))
             {
                 throw;
             }
             System.ServiceModel.DiagnosticUtility.ExceptionUtility.TraceHandledException(exception10, TraceEventType.Information);
             if (exception == null)
             {
                 exception = exception10;
             }
         }
     }
     if (System.ServiceModel.DiagnosticUtility.ShouldTraceInformation)
     {
         TraceUtility.TraceEvent(TraceEventType.Information, 0x40044, System.ServiceModel.SR.GetString("TraceCodePeerNodeClosed"), this.traceRecord, this, null);
     }
     if ((exception != null) && graceful)
     {
         throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(exception);
     }
 }
 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;
 }