Ejemplo n.º 1
0
        /// <summary>
        /// Removes a <see cref="DynDnsHostEntry" /> registration from the Dynamic
        /// DNS cluster.
        /// </summary>
        /// <param name="hostEntry">The host/IP address <see cref="DynDnsHostEntry" /> to be unregistered.</param>
        /// <remarks>
        /// <note>
        /// This method does not throw an exception if the registration is not present.
        /// </note>
        /// </remarks>
        /// <exception cref="InvalidOperationException">Thrown if the client has not been started.</exception>
        public void Unregister(DynDnsHostEntry hostEntry)
        {
            using (TimedLock.Lock(syncLock))
            {
                if (hosts.ContainsKey(hostEntry))
                {
                    // For UDP mode, we need to send two immediate Unregister message to each DNS
                    // server for the host entry.

                    if (settings.Mode == DynDnsMode.Udp && isOpen)
                    {
                        for (int i = 0; i < 2; i++)
                        {
                            DynDnsMessage message;
                            byte[]        packet;

                            message = new DynDnsMessage(DynDnsMessageFlag.OpUnregister, hostEntry);
                            packet  = message.ToArray(settings.SharedKey);

                            foreach (var nameServer in settings.NameServers)
                            {
                                socket.SendTo(packet, nameServer);
                            }
                        }
                    }

                    // Remove the host entry from the local table.

                    hosts.Remove(hostEntry);
                    Register();
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Handles background tasks when operating in UDP mode.
        /// </summary>
        /// <param name="state">Not used.</param>
        private void OnBkTask(object state)
        {
            try
            {
                using (TimedLock.Lock(syncLock))
                {
                    if (!isOpen || settings.Mode != DynDnsMode.Udp)
                    {
                        return;
                    }

                    if (settings.Domain.IsHost && domainRefreshTimer.HasFired)
                    {
                        // Perform a NS lookup for the domain and populate
                        // settings.NameServer with the results.

                        // $todo(jeff.lill):
                        //
                        // Note that I'm going to ignore any CNAME records returned
                        // for now.  It might be important to make sure these are
                        // added to the staticHosts table, but I need to think about
                        // this some more.

                        try
                        {
                            var         nameServers = new Dictionary <IPAddress, bool>();
                            string      qname;
                            DnsRequest  request;
                            DnsResponse response;

                            qname = settings.Domain.Host;
                            if (!qname.EndsWith("."))
                            {
                                qname += ".";
                            }

                            request  = new DnsRequest(DnsFlag.RD, qname, DnsQType.NS);
                            response = DnsResolver.QueryWithRetry(NetHelper.GetDnsServers(), request, TimeSpan.FromMilliseconds(500), 4);

                            if (response.RCode != DnsFlag.RCODE_OK)
                            {
                                SysLog.LogWarning("DynDnsClient: Domain NS query failed with error [{0}].", response.RCode);
                            }
                            else
                            {
                                // Build the set of name server endpoints by resolving the
                                // name server names returned in the NS response into IP addresses.

                                foreach (var answer in response.Answers)
                                {
                                    if (answer.RRType == DnsRRType.NS)
                                    {
                                        NS_RR nsAnswer = (NS_RR)answer;

                                        try
                                        {
                                            foreach (var address in Dns.GetHostAddresses(nsAnswer.NameServer).IPv4Only())
                                            {
                                                if (!nameServers.ContainsKey(address))
                                                {
                                                    nameServers.Add(address, true);
                                                }
                                            }
                                        }
                                        catch
                                        {
                                            // Ignorning
                                        }
                                    }
                                }

                                if (nameServers.Count == 0)
                                {
                                    // Note that I'm going to keep any name server addresses I already have
                                    // in the case where the name server queries above return nothing.  This
                                    // will give us some resiliency in the face of transient network problems, etc.
                                    // I'm going to set the timer to retry in 1 minute in this case.

                                    domainRefreshTimer.ResetTemporary(TimeSpan.FromMinutes(1));
                                }
                                else
                                {
                                    var newServers = new List <NetworkBinding>(nameServers.Count);

                                    foreach (var address in nameServers.Keys)
                                    {
                                        newServers.Add(new IPEndPoint(address, settings.Domain.Port));
                                    }

                                    settings.NameServers = newServers.ToArray();
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            domainRefreshTimer.Reset(TimeSpan.FromSeconds(60));
                            SysLog.LogException(e);
                        }
                    }

                    if (udpRegisterTimer.HasFired)
                    {
                        // It's time to transmit host registrations to the dynamic DNS servers.

                        DynDnsMessage message;
                        byte[]        packet;

                        foreach (var entry in hosts.Values)
                        {
                            message = new DynDnsMessage(DynDnsMessageFlag.OpRegister, entry);
                            packet  = message.ToArray(settings.SharedKey);

                            foreach (var nameServer in settings.NameServers)
                            {
                                socket.SendTo(packet, nameServer);
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                SysLog.LogException(e);
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Releases all resources associated with the instance.
        /// </summary>
        public void Close()
        {
            using (TimedLock.Lock(syncLock))
            {
                if (!isOpen)
                {
                    return;
                }

                // If we're running in UDP mode, then send a couple deregister messages
                // for all host entries to each known name server.  This will ensure that
                // the DNS updated quickly when servers are shut down gracefully.  Note
                // that I'm going to send duplicate messages to each server just to be
                // on the safe side.

                if (settings.Mode == DynDnsMode.Udp)
                {
                    for (int i = 0; i < 2; i++)
                    {
                        DynDnsMessage message;
                        byte[]        packet;

                        foreach (var entry in hosts.Values)
                        {
                            message = new DynDnsMessage(DynDnsMessageFlag.OpUnregister, entry);
                            packet  = message.ToArray(settings.SharedKey);

                            foreach (var nameServer in settings.NameServers)
                            {
                                socket.SendTo(packet, nameServer);
                            }

                            Thread.Sleep(500);
                        }
                    }
                }

                // Shut down the client.

                if (cluster != null)
                {
                    cluster.Stop();
                    cluster = null;
                }

                if (bkTimer != null)
                {
                    bkTimer.Dispose();
                    bkTimer = null;
                }

                if (socket != null)
                {
                    socket.Close();
                    socket = null;
                }

                router = null;
                isOpen = false;
            }
        }