예제 #1
0
 /// <summary>
 /// Constructor.
 /// </summary>
 public DynDnsClient()
 {
     this.syncLock = this;
     this.isOpen   = false;
     this.router   = null;
     this.cluster  = null;
     this.enabled  = false;
     this.settings = null;
     this.bkTimer  = null;
     this.hosts    = new Dictionary <DynDnsHostEntry, DynDnsHostEntry>();
 }
예제 #2
0
        /// <summary>
        /// Opens the <see cref="DynDnsClient" /> instance enabling it to join
        /// the Dynamic DNS Service cluster and to start replicating host/IP address
        /// associations.
        /// </summary>
        /// <param name="router">The <see cref="MsgRouter" /> to be associated with the client (or <c>null</c>).</param>
        /// <param name="settings">The <see cref="DynDnsClientSettings" /> to be used.</param>
        /// <exception cref="InvalidOperationException">Thrown if the instance is already open.</exception>
        /// <remarks>
        /// <note>
        /// The <see cref="ClusterMemberSettings" />' <see cref="ClusterMemberSettings.Mode" />
        /// property will be ignored and the instance aill join the cluster as an
        /// <see cref="ClusterMemberMode.Observer" />.  The rest of the member settings
        /// should be identical to the settings across all cluster instances to avoid
        /// strange protocol problems.
        /// </note>
        /// </remarks>
        public void Open(MsgRouter router, DynDnsClientSettings settings)
        {
            var orgMode = ClusterMemberMode.Unknown;

            if (this.isOpen)
            {
                throw new InvalidOperationException("DynDnsClient is already open.");
            }

            if (settings.Mode == DynDnsMode.Both)
            {
                throw new ArgumentException("DynDnsClient does not support [Mode=BOTH].");
            }

            this.isOpen   = true;
            this.settings = settings;

            // Make sure that the LillTek.Datacenter message types have been
            // registered with the LillTek.Messaging subsystem.

            LillTek.Datacenter.Global.RegisterMsgTypes();

            // Initialize

            enabled = settings.Enabled;
            if (!enabled)
            {
                return;
            }

            if (settings.Cluster != null)
            {
                orgMode = settings.Cluster.Mode;                // $hack(jeff.lill): This is a bit of a hack
                settings.Cluster.Mode = ClusterMemberMode.Observer;
            }

            foreach (var entry in settings.Hosts)
            {
                Register(entry);
            }

            try
            {
                using (TimedLock.Lock(syncLock))
                {
                    if (settings.Mode == DynDnsMode.Cluster)
                    {
                        if (router == null)
                        {
                            throw new ArgumentException("DynDnsClient requires a valid router when operating with [Mode=CLUSTER].");
                        }

                        if (settings.Cluster == null)
                        {
                            throw new ArgumentException("Cluster settings must be initialized when [Mode=CLUSTER].");
                        }

                        this.router  = router;
                        this.cluster = new ClusterMember(router, settings.Cluster);

                        foreach (DynDnsHostEntry host in settings.Hosts)
                        {
                            hosts[host] = host;
                        }

                        this.cluster.Start();

                        Register();     // Add any pre-existing host registrations to
                                        // the cluster member state
                    }
                    else if (settings.Mode == DynDnsMode.Udp)
                    {
                        this.udpRegisterTimer = new PolledTimer(settings.UdpRegisterInterval, true);
                        this.udpRegisterTimer.FireNow();

                        this.domainRefreshTimer = new PolledTimer(settings.DomainRefreshInterval, true);
                        this.domainRefreshTimer.FireNow();

                        this.bkTimer = new GatedTimer(new TimerCallback(OnBkTask), null, settings.BkInterval);

                        this.socket = new EnhancedSocket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                        this.socket.IgnoreUdpConnectionReset = true;
                        this.socket.Bind(settings.NetworkBinding);
                    }
                }
            }
            catch
            {
                Close();
                throw;
            }
            finally
            {
                if (settings.Cluster != null)
                {
                    settings.Cluster.Mode = orgMode;
                }
            }
        }