コード例 #1
0
        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;
        }
コード例 #2
0
        // Queued callback to actually process the address change
        // The design is such that any address change notifications are queued just like Open/Close operations.
        // So, we need not worry about address changes racing with other address changes or Open/Close operations.
        // Abort can happen at any time. However, Abort skips unregistering addresses, so this method doesn't have 
        // to worry about undoing its work if Abort happens.
        void OnIPAddressChange()
        {
            string lclMeshId = null;
            PeerNodeAddress nodeAddress = null;
            object lclResolverRegistrationId = null;
            bool lclRegistered = false;
            PeerIPHelper lclIPHelper = ipHelper;
            PeerNodeConfig lclconfig = config;
            bool processChange = false;
            TimeoutHelper timeoutHelper = new TimeoutHelper(ServiceDefaults.SendTimeout);

            // Determine if IP addresses have really changed before notifying the resolver
            // since it is possible that another change notification ahead of this one in the queue 
            // may have already completed notifying the resolver of the most current change.
            if (lclIPHelper != null && config != null)
            {
                nodeAddress = lclconfig.GetListenAddress(false);
                processChange = lclIPHelper.AddressesChanged(nodeAddress.IPAddresses);
                if (processChange)
                {
                    // Build the nodeAddress with the updated IP addresses
                    nodeAddress = new PeerNodeAddress(
                        nodeAddress.EndpointAddress, lclIPHelper.GetLocalAddresses());
                }
            }

            lock (ThisLock)
            {
                // Skip processing if the node isn't open anymore or if addresses haven't changed
                if (processChange && isOpen)
                {
                    lclMeshId = meshId;
                    lclResolverRegistrationId = resolverRegistrationId;
                    lclRegistered = registered;
                    config.SetListenAddress(nodeAddress);
                    completeTraceRecord = new PeerNodeTraceRecord(config.NodeId, meshId, nodeAddress);
                }
                else
                {
                    return;
                }
            }
            //#57954 - log and ---- non-critical exceptions during network change event notifications
            try
            {
                // Do we have any addresses? If so, update or re-register. Otherwise, unregister.
                if (nodeAddress.IPAddresses.Count > 0)
                {
                    if (lclRegistered)
                    {
                        resolver.Update(lclResolverRegistrationId, nodeAddress, timeoutHelper.RemainingTime());
                    }
                    else
                    {
                        RegisterAddress(lclMeshId, nodeAddress, timeoutHelper.RemainingTime());
                    }
                }
                else
                {
                    UnregisterAddress(timeoutHelper.RemainingTime());
                }
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e)) throw;
                DiagnosticUtility.TraceHandledException(e, TraceEventType.Warning);
            }
            PingConnections();

            if (DiagnosticUtility.ShouldTraceInformation)
            {
                TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.PeerNodeAddressChanged, SR.GetString(SR.TraceCodePeerNodeAddressChanged), this.completeTraceRecord, this, null);
            }
        }
コード例 #3
0
        // 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 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 OnIPAddressChange()
 {
     string lclMeshId = null;
     PeerNodeAddress listenAddress = null;
     object registrationId = null;
     bool registered = false;
     PeerIPHelper ipHelper = this.ipHelper;
     PeerNodeConfig config = this.config;
     bool flag2 = false;
     TimeoutHelper helper2 = new TimeoutHelper(ServiceDefaults.SendTimeout);
     if ((ipHelper != null) && (this.config != null))
     {
         listenAddress = config.GetListenAddress(false);
         flag2 = ipHelper.AddressesChanged(listenAddress.IPAddresses);
         if (flag2)
         {
             listenAddress = new PeerNodeAddress(listenAddress.EndpointAddress, ipHelper.GetLocalAddresses());
         }
     }
     lock (this.ThisLock)
     {
         if (flag2 && this.isOpen)
         {
             lclMeshId = this.meshId;
             registrationId = this.resolverRegistrationId;
             registered = this.registered;
             this.config.SetListenAddress(listenAddress);
             this.completeTraceRecord = new PeerNodeTraceRecord(this.config.NodeId, this.meshId, listenAddress);
         }
         else
         {
             return;
         }
     }
     try
     {
         if (listenAddress.IPAddresses.Count > 0)
         {
             if (registered)
             {
                 this.resolver.Update(registrationId, listenAddress, helper2.RemainingTime());
             }
             else
             {
                 this.RegisterAddress(lclMeshId, listenAddress, helper2.RemainingTime());
             }
         }
         else
         {
             this.UnregisterAddress(helper2.RemainingTime());
         }
     }
     catch (Exception exception)
     {
         if (Fx.IsFatal(exception))
         {
             throw;
         }
         System.ServiceModel.DiagnosticUtility.ExceptionUtility.TraceHandledException(exception, TraceEventType.Warning);
     }
     this.PingConnections();
     if (System.ServiceModel.DiagnosticUtility.ShouldTraceInformation)
     {
         TraceUtility.TraceEvent(TraceEventType.Information, 0x4003f, System.ServiceModel.SR.GetString("TraceCodePeerNodeAddressChanged"), this.completeTraceRecord, this, null);
     }
 }