public PeerNeighborManager(PeerIPHelper ipHelper, PeerNodeConfig config, IPeerNodeMessageHandling messageHandler)
        {
            Fx.Assert(ipHelper != null, "Non-null ipHelper is expected");
            Fx.Assert(config != null, "Non-null Config is expected");

            this.neighborList = new List<PeerNeighbor>();
            this.connectedNeighborList = new List<IPeerNeighbor>();
            this.ipHelper = ipHelper;
            this.messageHandler = messageHandler;
            this.config = config;
            this.thisLock = new object();
            this.traceRecord = new PeerNodeTraceRecord(config.NodeId);
            this.state = State.Created;
        }
        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));
            }
        }
 public PeerNeighborManager(PeerIPHelper ipHelper, PeerNodeConfig config)
     :
     this(ipHelper, config, null) { }
        public PeerNodeAddress GetListenAddress(bool maskScopeId)
        {
            PeerNodeAddress listenAddress = this.listenAddress;

            return(new PeerNodeAddress(listenAddress.EndpointAddress, PeerIPHelper.CloneAddresses(listenAddress.IPAddresses, maskScopeId)));
        }
 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);
     }
 }