예제 #1
0
        // Register a node address for a given mesh ID
        public int Register(string meshId, PeerNodeAddress nodeAddress)
        {
            bool newMeshId = false;
            int registrationId;
            Registration registration = new Registration(meshId, nodeAddress);

            // Add the new registration to the registration table; update meshIdTable with the newly registered nodeAddress
            lock (registrationTable)
            {
                registrationId = nextRegistrationId++;
                lock (meshIdTable)
                {
                    // Update the meshId table
                    Dictionary<int, PeerNodeAddress> addresses;
                    if (!meshIdTable.TryGetValue(meshId, out addresses))
                    {
                        // MeshID doesn't exist and needs to be added to meshIdTable
                        newMeshId = true;
                        addresses = new Dictionary<int, PeerNodeAddress>();
                        meshIdTable[meshId] = addresses;
                    }
                    addresses[registrationId] = nodeAddress;

                    // Add an entry to the registration table
                    registrationTable[registrationId] = new Registration(meshId, nodeAddress);
                }
            }
            if (newMeshId)
                Console.WriteLine("Registered new meshId {0}", meshId);
            return registrationId;
        }
예제 #2
0
 public UpdateInfoDC(Guid registrationId, Guid client, string meshId, PeerNodeAddress address)
 {
     this.ClientId = client;
     this.MeshId = meshId;
     this.NodeAddress = address;
     this.RegistrationId = registrationId;
 }
 public override object Register(string meshId, PeerNodeAddress nodeAddress, TimeSpan timeout)
 {
     if (this.opened)
     {
         long scopeId = -1L;
         bool flag = false;
         if (nodeAddress.IPAddresses.Count == 0)
         {
             throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(System.ServiceModel.SR.GetString("MustRegisterMoreThanZeroAddresses")));
         }
         foreach (IPAddress address in nodeAddress.IPAddresses)
         {
             if (address.IsIPv6LinkLocal)
             {
                 if (scopeId == -1L)
                 {
                     scopeId = address.ScopeId;
                 }
                 else if (scopeId != address.ScopeId)
                 {
                     flag = true;
                     break;
                 }
             }
         }
         List<IPAddress> list = new List<IPAddress>();
         foreach (IPAddress address2 in nodeAddress.IPAddresses)
         {
             if (!flag || (!address2.IsIPv6LinkLocal && !address2.IsIPv6SiteLocal))
             {
                 list.Add(address2);
             }
         }
         if (list.Count == 0)
         {
             throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(System.ServiceModel.SR.GetString("AmbiguousConnectivitySpec")));
         }
         ReadOnlyCollection<IPAddress> ipAddresses = new ReadOnlyCollection<IPAddress>(list);
         this.meshId = meshId;
         this.nodeAddress = new PeerNodeAddress(nodeAddress.EndpointAddress, ipAddresses);
         RegisterInfo registerInfo = new RegisterInfo(this.clientId, meshId, this.nodeAddress);
         IPeerResolverClient proxy = this.GetProxy();
         try
         {
             proxy.OperationTimeout = timeout;
             RegisterResponseInfo info2 = proxy.Register(registerInfo);
             this.registrationId = info2.RegistrationId;
             this.timer.Set(info2.RegistrationLifetime);
             this.defaultLifeTime = info2.RegistrationLifetime;
             proxy.Close();
         }
         finally
         {
             proxy.Abort();
         }
     }
     return this.registrationId;
 }
 public RegistrationEntry(Guid clientId, Guid registrationId, string meshId, DateTime expires, PeerNodeAddress address)
 {
     this.ClientId = clientId;
     this.RegistrationId = registrationId;
     this.MeshId = meshId;
     this.Expires = expires;
     this.Address = address;
     this.State = RegistrationState.OK;
 }
 public PeerNeighborTraceRecord(ulong remoteNodeId, ulong localNodeId, PeerNodeAddress listenAddress, IPAddress connectIPAddress, int hashCode, bool initiator, string state, string previousState, string attemptedState, string action)
 {
     this.localNodeId = localNodeId;
     this.remoteNodeId = remoteNodeId;
     this.listenAddress = listenAddress;
     this.connectIPAddress = connectIPAddress;
     this.hashCode = hashCode;
     this.initiator = initiator;
     this.state = state;
     this.previousState = previousState;
     this.attemptedState = attemptedState;
     this.action = action;
 }
	public void ResolveResponseInfo ()
	{
		var ser = new DataContractSerializer (typeof (ResolveResponseInfo));
		var rri = new ResolveResponseInfo ();
		var pna = new PeerNodeAddress (
			new EndpointAddress ("http://localhost:8080"),
			new ReadOnlyCollection<IPAddress> (new IPAddress [0]));
		rri.Addresses = new List<PeerNodeAddress> ();
		rri.Addresses.Add (pna);
		var sw = new StringWriter ();
		using (var xw = XmlWriter.Create (sw))
			ser.WriteObject (xw, rri);
		rri = (ResolveResponseInfo) ser.ReadObject (XmlReader.Create (new StringReader (sw.ToString ())));
	}
 public static bool ValidReferralNodeAddress(PeerNodeAddress address)
 {
     long scopeId = -1L;
     foreach (IPAddress address2 in address.IPAddresses)
     {
         if (address2.IsIPv6LinkLocal)
         {
             if (scopeId == -1L)
             {
                 scopeId = address2.ScopeId;
             }
             else if (scopeId != address2.ScopeId)
             {
                 return false;
             }
         }
     }
     return true;
 }
 private void RegisterAddress(string lclMeshId, PeerNodeAddress nodeAddress, TimeSpan timeout)
 {
     if (nodeAddress.IPAddresses.Count > 0)
     {
         object obj2 = null;
         try
         {
             obj2 = this.resolver.Register(lclMeshId, nodeAddress, timeout);
         }
         catch (Exception exception)
         {
             if (Fx.IsFatal(exception))
             {
                 throw;
             }
             throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(System.ServiceModel.SR.GetString("ResolverException"), exception));
         }
         lock (this.ThisLock)
         {
             if (this.registered)
             {
                 throw Fx.AssertAndThrow("registered expected to be false");
             }
             this.registered = true;
             this.resolverRegistrationId = obj2;
         }
     }
 }
 // Updates a node's registration with the resolver service.
 public override void Update(object registrationId, PeerNodeAddress updatedNodeAddress, TimeSpan timeout)
 {
     if (opened)
     {
         UpdateInfo info = new UpdateInfo(this.registrationId, clientId, meshId, updatedNodeAddress);
         this.nodeAddress = updatedNodeAddress;
         SendUpdate(info, timeout);
     }
 }
 public override object Register(string meshId,
                                 PeerNodeAddress nodeAddress, TimeSpan timeout)
 {
     throw new NotImplementedException();
 }
        // 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));
            }
        }
        // Find a duplicate neighbor (excluding skipNeighbor) matching the address.
        public IPeerNeighbor FindDuplicateNeighbor(PeerNodeAddress address, IPeerNeighbor skipNeighbor)
        {
            PeerNeighbor duplicateNeighbor = null;

            lock (ThisLock)
            {
                foreach (PeerNeighbor neighbor in this.neighborList)
                {
                    // We restrict search to neighbors that are not yet closing.
                    if (neighbor != (PeerNeighbor)skipNeighbor &&
                        neighbor.ListenAddress != null &&
                        neighbor.ListenAddress.ServicePath == address.ServicePath &&
                        !neighbor.IsClosing &&
                        neighbor.State < PeerNeighborState.Disconnecting)
                    {
                        duplicateNeighbor = neighbor;
                        break;
                    }
                }
            }
            return duplicateNeighbor;
        }
            // ClosedCallback is a delegate to determine if caller has closed. If so, we bail out of open operation
            public NeighborOpenAsyncResult(PeerNeighbor neighbor, PeerNodeAddress remoteAddress, Binding binding,
                PeerService service, ClosedCallback closedCallback, TimeSpan timeout, AsyncCallback callback, object state)
                : base(callback, state)
            {
                this.neighbor = neighbor;

                IAsyncResult result = null;
                try
                {
                    result = neighbor.BeginOpen(remoteAddress, binding, service, closedCallback, timeout,
                        Fx.ThunkCallback(new AsyncCallback(OnOpen)), null);
                    if (result.CompletedSynchronously)
                    {
                        neighbor.EndOpen(result);
                    }
                }
                catch (Exception e)
                {
                    if (Fx.IsFatal(e)) throw;
                    neighbor.TraceEventHelper(TraceEventType.Warning, TraceCode.PeerNeighborOpenFailed, SR.GetString(SR.TraceCodePeerNeighborOpenFailed));
                    throw;
                }

                // Indicate [....] completion to the caller
                if (result.CompletedSynchronously)
                    base.Complete(true);
            }
                public OpenAsyncResult(PeerNeighbor neighbor, PeerNodeAddress remoteAddress, Binding binding,
                    PeerService service, ClosedCallback closedCallback, TimeSpan timeout,
                    AsyncCallback callback, object state)
                    : base(callback, state)
                {
                    Fx.Assert(remoteAddress != null && remoteAddress.IPAddresses.Count > 0, "Non-empty IPAddress collection expected");

                    this.timeoutHelper = new TimeoutHelper(timeout);
                    this.neighbor = neighbor;
                    this.currentIndex = 0;
                    this.completedSynchronously = true;         // initially
                    this.remoteAddress = remoteAddress;
                    this.service = service;
                    this.binding = binding;
                    this.onOpen = Fx.ThunkCallback(new AsyncCallback(OnOpen));
                    this.closed = closedCallback;
                    BeginOpen();
                }
 // Begin opening of a neighbor channel to 'to'. instanceContext is where the remote 
 // endpoint should send messages to (it will be a reference to PeerNeighborManager).
 public IAsyncResult BeginOpen(PeerNodeAddress remoteAddress, Binding binding,
     PeerService service, ClosedCallback closedCallback, TimeSpan timeout,
     AsyncCallback callback, object asyncState)
 {
     this.initiator = true;
     this.listenAddress = remoteAddress;
     OpenAsyncResult result = new OpenAsyncResult(this, remoteAddress, binding, service,
         closedCallback, timeout, callback, state);
     return result;
 }
 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);
     }
 }
 public RegisterInfoDC(Guid client, string meshId, PeerNodeAddress address)
 {
     this.ClientId = client;
     this.MeshId = meshId;
     this.NodeAddress = address;
 }
예제 #19
0
 public abstract void Update(object registrationId,
                             PeerNodeAddress updatedNodeAddress, TimeSpan timeout);
예제 #20
0
 public abstract object Register(string meshId,
                                 PeerNodeAddress nodeAddress, TimeSpan timeout);
예제 #21
0
 public UpdateInfo(Guid registrationId, Guid client, string meshId, PeerNodeAddress address)
 {
     body = new UpdateInfoDC(registrationId, client, meshId, address);
 }
예제 #22
0
		public override object Register (string meshId,
			PeerNodeAddress nodeAddress, TimeSpan timeout)
		{
			throw new NotImplementedException ();
		}
        public IAsyncResult BeginOpenNeighbor(PeerNodeAddress remoteAddress, TimeSpan timeout, AsyncCallback callback, object asyncState)
        {
            ThrowIfNotOpen();

            // It's okay if neighbor manager is shutdown and closed after the above check 
            // because the new neighbor is only added to neighborList in NeighborOpened 
            // handler if the neighbor manager is still open.

            // Sort the IP addresses
            ReadOnlyCollection<IPAddress> sortedAddresses = this.ipHelper.SortAddresses(remoteAddress.IPAddresses);
            PeerNodeAddress address = new PeerNodeAddress(remoteAddress.EndpointAddress, sortedAddresses);
            return BeginOpenNeighborInternal(address, timeout, callback, asyncState);
        }
예제 #24
0
		public override void Update (object registrationId,
			PeerNodeAddress updatedNodeAddress, TimeSpan timeout)
		{
			throw new NotImplementedException ();
		}
        internal IAsyncResult BeginOpenNeighborInternal(PeerNodeAddress remoteAddress, TimeSpan timeout, AsyncCallback callback, object asyncState)
        {
            PeerNeighbor neighbor = new PeerNeighbor(this.config, this.messageHandler);
            RegisterForNeighborEvents(neighbor);

            return new NeighborOpenAsyncResult(neighbor, remoteAddress, this.serviceBinding, this.service,
                new ClosedCallback(Closed), timeout, callback, asyncState);
        }
        PeerNodeAddress address;    // Referral address

        public Referral(ulong nodeId, PeerNodeAddress address)
        {
            this.nodeId = nodeId;
            this.address = address;
        }
 // Find a duplicate neighbor matching the address
 public IPeerNeighbor FindDuplicateNeighbor(PeerNodeAddress address)
 {
     return FindDuplicateNeighbor(address, null);
 }
 public ConnectInfoDC(ulong nodeId, PeerNodeAddress address)
 {
     this.nodeId = nodeId;
     this.address = address;
 }
 // Register with the resolver
 void RegisterAddress(string lclMeshId, PeerNodeAddress nodeAddress, TimeSpan timeout)
 {
     // Register only if we have any addresses
     if (nodeAddress.IPAddresses.Count > 0)
     {
         object lclResolverRegistrationId = null;
         try
         {
             lclResolverRegistrationId = resolver.Register(lclMeshId, nodeAddress, timeout);
         }
         catch (Exception e)
         {
             if (Fx.IsFatal(e)) throw;
             throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(SR.GetString(SR.ResolverException), e));
         }
         lock (ThisLock)
         {
             if (!(!registered))
             {
                 throw Fx.AssertAndThrow("registered expected to be false");
             }
             registered = true;
             resolverRegistrationId = lclResolverRegistrationId;
         }
     }
 }
 public ConnectInfo(ulong nodeId, PeerNodeAddress address)
 {
     this.body = new ConnectInfoDC(nodeId, address);
 }
        // 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);
            }
        }
 public void SetListenAddress(PeerNodeAddress address)
 {
     this.listenAddress = address;
 }
 public override void Update(object registrationId,
                             PeerNodeAddress updatedNodeAddress, TimeSpan timeout)
 {
     throw new NotImplementedException();
 }
        // Register address for a node participating in a mesh identified by meshId with the resolver service
        public override object Register(string meshId, PeerNodeAddress nodeAddress, TimeSpan timeout)
        {
            if (opened)
            {

                long scopeId = -1;
                bool multipleScopes = false;

                if (nodeAddress.IPAddresses.Count == 0)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.MustRegisterMoreThanZeroAddresses)));
                }

                foreach (IPAddress address in nodeAddress.IPAddresses)
                {
                    if (address.IsIPv6LinkLocal)
                    {
                        if (scopeId == -1)
                        {
                            scopeId = address.ScopeId;
                        }
                        else if (scopeId != address.ScopeId)
                        {
                            multipleScopes = true;
                            break;
                        }
                    }
                }

                List<IPAddress> addresslist = new List<IPAddress>();
                foreach (IPAddress address in nodeAddress.IPAddresses)
                {
                    if (!multipleScopes || (!address.IsIPv6LinkLocal && !address.IsIPv6SiteLocal))
                        addresslist.Add(address);
                }

                if (addresslist.Count == 0)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(SR.GetString(SR.AmbiguousConnectivitySpec)));
                }

                ReadOnlyCollection<IPAddress> addresses = new ReadOnlyCollection<IPAddress>(addresslist);
                this.meshId = meshId;
                this.nodeAddress = new PeerNodeAddress(nodeAddress.EndpointAddress, addresses);
                RegisterInfo info = new RegisterInfo(clientId, meshId, this.nodeAddress);
                IPeerResolverClient proxy = GetProxy();
                try
                {
                    proxy.OperationTimeout = timeout;
                    RegisterResponseInfo response = proxy.Register(info);
                    this.registrationId = response.RegistrationId;
                    timer.Set(response.RegistrationLifetime);
                    this.defaultLifeTime = response.RegistrationLifetime;
                    proxy.Close();
                }
                finally
                {
                    proxy.Abort();
                }
            }
            return registrationId;
        }