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