Esempio n. 1
0
        private void SetIaPdT1(DhcpLink clientLink, DhcpV6IaPdOption iaPdOption, long minPreferredLifetime)
        {
            float t1 = DhcpServerPolicies.EffectivePolicyAsFloat(this.clientLink.GetLink(), Property.IA_PD_T1);

            if ((t1 > 1))
            {
                log.Debug(("Setting IA_PD T1 to configured number of seconds: " + t1));
                //  if T1 is greater than one, then treat it as an
                //  absolute value which specifies the number of seconds
                iaPdOption.SetT1(((long)(t1)));
            }
            else
            {
                //  if T1 is less than one and greater than or equal to zero,
                //  then treat is as a percentage of the minimum preferred lifetime
                //  unless the minimum preferred lifetime is infinity (0xffffffff)
                if ((minPreferredLifetime == 4294967295))
                {
                    log.Debug(("Setting IA_PD T1 to minPreferredLifetime of infinity: " + minPreferredLifetime));
                    iaPdOption.SetT1(minPreferredLifetime);
                }
                else if ((t1 >= 0))
                {
                    //  zero means let the client decide
                    log.Debug(("Setting IA_PD T1 to configured ratio="
                               + (t1 + (" of minPreferredLifetime=" + minPreferredLifetime))));
                    iaPdOption.SetT1(((long)((t1 * minPreferredLifetime))));
                }
                else
                {
                    log.Debug(("Setting IA_PD T1 to standard ratio=0.5" + (" of minPreferredLifetime=" + minPreferredLifetime)));
                    iaPdOption.SetT1(((long)((0.5 * minPreferredLifetime))));
                }
            }
        }
Esempio n. 2
0
 /// <summary>
 /// Release an IaAddress.  If policy dictates, the address will be deleted,
 /// otherwise the state will be marked as released instead.  In either case,
 /// a DDNS delete will be issued for the address binding.
 /// </summary>
 /// <param name="ia">iaAddr the IaAddress to be released</param>
 /// <param name="iaAddr">iaAddr the IaAddress to be released</param>
 public void ReleaseIaAddress(IdentityAssoc ia, IaAddress iaAddr)
 {
     try
     {
         log.Info("Releasing address: " + iaAddr.GetIpAddress().ToString());
         //DdnsDelete(ia, iaAddr);
         if (DhcpServerPolicies.GlobalPolicyAsBoolean(
                 Property.BINDING_MANAGER_DELETE_OLD_BINDINGS))
         {
             iaMgr.DeleteIaAddr(iaAddr);
             // free the address only if it is deleted from the db,
             // otherwise, we will get a unique constraint violation
             // if another client obtains this released IP address
             FreeAddress(iaAddr.GetIpAddress());
         }
         else
         {
             iaAddr.SetStartTime(DateTime.Now);
             iaAddr.SetPreferredEndTime(DateTime.Now);
             iaAddr.SetValidEndTime(DateTime.Now);
             iaAddr.SetState(IaAddress.RELEASED);
             iaMgr.UpdateIaAddr(iaAddr);
             log.Info("Address released: " + iaAddr.ToString());
         }
     }
     catch (Exception ex)
     {
         log.Error("Failed to release address");
     }
 }
Esempio n. 3
0
        //Populate v4 options.
        //@param link the link
        //@param configObj the config object or null if none
        protected void PopulateV4Reply(DhcpLink dhcpLink, DhcpV4OptionConfigObject configObj)
        {
            string sname = DhcpServerPolicies.EffectivePolicy(_requestMsg, configObj,
                                                              dhcpLink.GetLink(), Property.V4_HEADER_SNAME);

            if (!String.IsNullOrEmpty(sname))
            {
                _replyMsg.SetsName(sname);
            }

            string filename = DhcpServerPolicies.EffectivePolicy(_requestMsg, configObj,
                                                                 dhcpLink.GetLink(), Property.V4_HEADER_FILENAME);

            if (!String.IsNullOrEmpty(filename))
            {
                _replyMsg.SetFile(filename);
            }

            Dictionary <int, DhcpOption> optionMap =
                _dhcpServerConfig.EffectiveV4AddrOptions(_requestMsg, dhcpLink, configObj);

            if (DhcpServerPolicies.EffectivePolicyAsBoolean(configObj,
                                                            dhcpLink.GetLink(), Property.SEND_REQUESTED_OPTIONS_ONLY))
            {
                optionMap = RequestedOptions(optionMap, _requestMsg);
            }
            _replyMsg.PutAllDhcpOptions(optionMap);

            // copy the relay agent info option from request to reply
            // in order to echo option back to router as required
            if (_requestMsg.HasOption(DhcpConstants.V4OPTION_RELAY_INFO))
            {
                _requestMsg.PutDhcpOption(_requestMsg.GetDhcpOption(DhcpConstants.V4OPTION_RELAY_INFO));
            }
        }
 /**
  * Callback from the ExpireTimerTask started when the lease was granted.
  * NOT CURRENTLY USED
  *
  * @param iaPrefix the ia prefix
  */
 public void ExpireIaPrefix(IaPrefix iaPrefix)
 {
     try
     {
         if (DhcpServerPolicies.GlobalPolicyAsBoolean(
                 Property.BINDING_MANAGER_DELETE_OLD_BINDINGS))
         {
             log.Debug("Deleting expired prefix: " + iaPrefix.GetIpAddress());
             iaMgr.DeleteIaPrefix(iaPrefix);
             // free the prefix only if it is deleted from the db,
             // otherwise, we will get a unique constraint violation
             // if another client obtains this released prefix
             FreeAddress(iaPrefix.GetIpAddress());
         }
         else
         {
             iaPrefix.SetStartTime(DateTime.Now);
             iaPrefix.SetPreferredEndTime(DateTime.Now);
             iaPrefix.SetValidEndTime(DateTime.Now);
             iaPrefix.SetState(IaPrefix.EXPIRED);
             log.Debug("Updating expired prefix: " + iaPrefix.GetIpAddress());
             iaMgr.UpdateIaPrefix(iaPrefix);
         }
     }
     catch (Exception ex)
     {
         log.Error("Failed to expire address");
     }
 }
        /**
         * Builds a binding pool from an V4AddressPool using the given link and filter.
         *
         * @param pool the V4AddressPool to wrap as an V4AddressBindingPool
         * @param link the link
         * @param linkFilter the link filter
         *
         * @return the binding pool
         *
         * @throws DhcpServerConfigException if there is a problem parsing the configured range
         */
        protected V4AddressBindingPool BuildV4BindingPool(v4AddressPool pool, link link,
                                                          linkFilter linkFilter)
        {
            V4AddressBindingPool bp = new V4AddressBindingPool(pool);
            long leasetime          =
                DhcpServerPolicies.EffectivePolicyAsLong(bp, link, Property.V4_DEFAULT_LEASETIME);

            bp.SetLeasetime(leasetime);
            bp.SetLinkFilter(linkFilter);

            List <IPAddress> usedIps = iaMgr.FindExistingIPs(bp.GetStartAddress(), bp.GetEndAddress());

            if ((usedIps != null) && usedIps.Count > 0)
            {
                foreach (IPAddress ip in usedIps)
                {
                    //TODO: for the quickest startup?...
                    // set IP as used without checking if the binding has expired
                    // let the reaper thread deal with all binding cleanup activity
                    bp.SetUsed(ip);
                }
            }
            log.Info("Built v4 address binding pool: " + bp.GetStartAddress().ToString() + "-" +
                     bp.GetEndAddress().ToString() + " size=" + bp.GetSize());
            return(bp);
        }
        /**
         * Builds a binding pool from an PrefixPool using the given link and filter.
         *
         * @param pool the AddressPool to wrap as an PrefixBindingPool
         * @param link the link
         * @param linkFilter the link filter
         *
         * @return the binding pool
         *
         * @throws DhcpServerConfigException if there is a problem parsing the configured range
         */
        protected V6PrefixBindingPool BuildV6BindingPool(v6PrefixPool pool, link link,
                                                         linkFilter linkFilter)
        {
            V6PrefixBindingPool bp = new V6PrefixBindingPool(pool);
            long pLifetime         =
                DhcpServerPolicies.EffectivePolicyAsLong(bp, link, Property.PREFERRED_LIFETIME);

            bp.SetPreferredLifetime(pLifetime);
            long vLifetime =
                DhcpServerPolicies.EffectivePolicyAsLong(bp, link, Property.VALID_LIFETIME);

            bp.SetValidLifetime(vLifetime);
            bp.SetLinkFilter(linkFilter);

            List <IPAddress> usedIps = iaMgr.FindExistingIPs(bp.GetStartAddress(), bp.GetEndAddress());

            if ((usedIps != null) && usedIps.Count > 0)
            {
                foreach (IPAddress ip in usedIps)
                {
                    //TODO: for the quickest startup?...
                    // set IP as used without checking if the binding has expired
                    // let the reaper thread deal with all binding cleanup activity
                    bp.SetUsed(ip);
                }
            }
            log.Info("Built prefix binding pool: " + bp.GetStartAddress().ToString() + "-" +
                     bp.GetEndAddress().ToString() + ", size=" + bp.GetSize());
            return(bp);
        }
Esempio n. 7
0
        /// <summary>
        /// 是否開啟快速提交模式
        /// </summary>
        /// <param name="requestMsg"></param>
        /// <param name="clientLink"></param>
        /// <returns></returns>
        private bool IsRapidCommit(DhcpV6Message requestMsg, link clientLink)
        {
            if ((requestMsg.HasOption(DhcpConstants.V6OPTION_RAPID_COMMIT) && DhcpServerPolicies.EffectivePolicyAsBoolean(requestMsg, clientLink, Property.SUPPORT_RAPID_COMMIT)))
            {
                return(true);
            }

            return(false);
        }
Esempio n. 8
0
        protected void PopulatePrefixOptions(DhcpV6IaPrefixOption iaPrefixOption, DhcpLink dhcpLink, DhcpV6OptionConfigObject configObj)
        {
            Dictionary <int, DhcpOption> optionMap = dhcpServerConfig.EffectivePrefixOptions(this.requestMsg, dhcpLink, configObj);

            if (DhcpServerPolicies.EffectivePolicyAsBoolean(configObj, dhcpLink.GetLink(), Property.SEND_REQUESTED_OPTIONS_ONLY))
            {
                optionMap = this.RequestedOptions(optionMap, this.requestMsg);
            }

            iaPrefixOption.PutAllDhcpOptions(optionMap);
        }
Esempio n. 9
0
        protected void PopulatePrefixOptions(DhcpV6IaPrefixOption iaPrefixOption)
        {
            Dictionary <int, DhcpOption> optionMap = dhcpServerConfig.EffectivePrefixOptions(this.requestMsg);

            if (DhcpServerPolicies.GlobalPolicyAsBoolean(Property.SEND_REQUESTED_OPTIONS_ONLY))
            {
                optionMap = this.RequestedOptions(optionMap, this.requestMsg);
            }

            iaPrefixOption.PutAllDhcpOptions(optionMap);
        }
        protected override void StartReaper()
        {
            //TODO: separate properties for address/prefix binding managers?
            long reaperStartupDelay =
                DhcpServerPolicies.GlobalPolicyAsLong(Property.BINDING_MANAGER_REAPER_STARTUP_DELAY);
            long reaperRunPeriod =
                DhcpServerPolicies.GlobalPolicyAsLong(Property.BINDING_MANAGER_REAPER_RUN_PERIOD);

            //reaper = new Timer("BindingReaper");
            //reaper.schedule(new ReaperTimerTask(), reaperStartupDelay, reaperRunPeriod);
        }
Esempio n. 11
0
        /// <summary>
        /// Populate reply msg options.
        /// </summary>
        /// <param name="dhcpLink">the link</param>
        protected void PopulateReplyMsgOptions(DhcpLink dhcpLink)
        {
            Dictionary <int, DhcpOption> optionMap = dhcpServerConfig.EffectiveMsgOptions(this.requestMsg, dhcpLink);

            if (DhcpServerPolicies.EffectivePolicyAsBoolean(dhcpLink.GetLink(), Property.SEND_REQUESTED_OPTIONS_ONLY))
            {
                optionMap = this.RequestedOptions(optionMap, this.requestMsg);
            }

            replyMsg.PutAllDhcpOptions(optionMap);
        }
Esempio n. 12
0
        /// <summary>
        /// Gets the next available address in this address pool.
        /// </summary>
        /// <returns>the next available address</returns>
        public IPAddress GetNextAvailableAddress()
        {
            Monitor.Enter(_lock);
            try
            {
                if (freeList != null)
                {
                    BigInteger next = freeList.GetNextFree();
                    if (next.IntValue() != 0)
                    {
                        try
                        {
                            IPAddress ip = new IPAddress(next.GetBytes());
                            int       pingCheckTimeout = DhcpServerPolicies.GlobalPolicyAsInt(Property.V4_PINGCHECK_TIMEOUT);
                            if (pingCheckTimeout > 0)
                            {
                                try
                                {
                                    if (CheckIPIsUsed(ip, pingCheckTimeout))
                                    {
                                        log.Warn("Next free address answered ping check: " + ip.ToString());

                                        SetUsed(ip);
                                        return(GetNextAvailableAddress());   // try again
                                    }
                                    log.InfoFormat("Assign IPv4 Address : {0}", ip.ToString());
                                }
                                catch (IOException ex)
                                {
                                    log.Error("Failed to perform v4 ping check: " + ex);
                                }
                            }
                            return(ip);
                        }
                        catch (Exception ex)
                        {
                            log.Error("Unable to build IPv4 address from next free: " + ex);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                log.Error("Unable to build IPv4 address from next free: " + ex);
            }
            finally
            {
                Monitor.Exit(_lock);
            }
            return(null);
        }
Esempio n. 13
0
        private void SetIaPdT2(DhcpLink clientLink, DhcpV6IaPdOption iaPdOption, long minPreferredLifetime)
        {
            float t2 = DhcpServerPolicies.EffectivePolicyAsFloat(this.clientLink.GetLink(), Property.IA_PD_T2);

            if ((t2 > 1))
            {
                log.Debug(("Setting IA_PD T2 to configured number of seconds: " + t2));
                iaPdOption.SetT2(((long)(t2)));
            }
            else
            {
                //  if T2 is less than one and greater than or equal to zero,
                //  then treat is as a percentage of the minimum preferred lifetime
                //  unless the minimum preferred lifetime is infinity (0xffffffff)
                if ((minPreferredLifetime == 4294967295))
                {
                    log.Debug(("Setting IA_PD T2 to minPreferredLifetime of infinity: " + minPreferredLifetime));
                    iaPdOption.SetT2(minPreferredLifetime);
                }
                else if ((t2 >= 0))
                {
                    //  zero means let the client decide
                    log.Debug(("Setting IA_PD T2 to configured ratio="
                               + (t2 + (" of minPreferredLifetime=" + minPreferredLifetime))));
                    iaPdOption.SetT2(((long)((t2 * minPreferredLifetime))));
                }
                else
                {
                    log.Debug(("Setting IA_PD T2 to standard ratio=0.8" + (" of minPreferredLifetime=" + minPreferredLifetime)));
                    iaPdOption.SetT2(((long)((0.8 * minPreferredLifetime))));
                }
            }

            //  ensure that T2 >= T1
            if ((iaPdOption.GetT2() < iaPdOption.GetT1()))
            {
                log.Warn((" IA_PD T2("
                          + (iaPdOption.GetT2() + (")" + (" <  IA_PD T1("
                                                          + (iaPdOption.GetT1() + "): setting T2=T1"))))));
                iaPdOption.SetT2(iaPdOption.GetT1());
            }
        }
Esempio n. 14
0
        public List <IaAddress> FindUnusedIaAddresses(IPAddress startAddr, IPAddress endAddr)
        {
            long offerExpireMillis =
                DhcpServerPolicies.GlobalPolicyAsLong(Property.BINDING_MANAGER_OFFER_EXPIRATION);
            long offerExpiration = OpaqueDataUtil.GetCurrentMilli() - offerExpireMillis;

            List <DhcpLease> leases = _DhcpLeaseData.Where(d =>
                                                           ((d.GetState() == IaAddress.ADVERTISED &&
                                                             d.GetStartTime() <= new DateTime(offerExpiration)) |
                                                            (d.GetState() == IaAddress.EXPIRED |
                                                             d.GetState() == IaAddress.RELEASED)) &&
                                                           d.GetIpAddress().GetLong() >= startAddr.GetLong() &&
                                                           d.GetIpAddress().GetLong() <= endAddr.GetLong()).
                                      OrderBy(s => s.GetState()).
                                      ThenBy(t => t.GetValidEndTime()).
                                      //ThenBy(d => d.GetIpAddress())
                                      ToList();

            return(ToIaAddresses(leases));
        }
Esempio n. 15
0
        private bool IsIgnoredMac(byte[] chAddr)
        {
            string ignoredMacPolicy = DhcpServerPolicies.GlobalPolicy(Property.V4_IGNORED_MACS);

            if (ignoredMacPolicy != null)
            {
                string[] ignoredMacs = ignoredMacPolicy.Split(',');
                if (ignoredMacs != null)
                {
                    foreach (var ignoredMac in ignoredMacs)
                    {
                        if (ignoredMac.Trim().ToUpper().Equals(Util.ToHexString(chAddr).ToUpper()))
                        {
                            return(true);
                        }
                    }
                }
            }
            return(false);
        }
        /// <summary>
        /// Gets the next available address in this address pool.
        /// </summary>
        /// <returns>the next available address</returns>
        public IPAddress GetNextAvailableAddress()
        {
            Debug.Assert(CheckIPIsUsed != null, "V6AddressBindingPool --GetNextAvailableAddress-- CheckIPIsUsed = null");
            if (freeList != null)
            {
                BigInteger next = freeList.GetNextFree();
                if (next.IntValue() != 0)
                {
                    try
                    {
                        byte[]    nextByte         = next.GetBytes();
                        IPAddress ip               = new IPAddress(next.GetBytes());
                        int       pingCheckTimeout = DhcpServerPolicies.GlobalPolicyAsInt(Property.V4_PINGCHECK_TIMEOUT);
                        if (pingCheckTimeout > 0)
                        {
                            try
                            {
                                if (CheckIPIsUsed(ip, pingCheckTimeout))
                                {
                                    log.Warn("Next free address answered ping check: " + ip.ToString());

                                    SetUsed(ip);
                                    return(GetNextAvailableAddress());   // try again
                                }
                                log.InfoFormat("Assign IPv6 Address : {0}", ip.ToString());
                            }
                            catch (IOException ex)
                            {
                                log.Error("Failed to perform v4 ping check: " + ex);
                            }
                        }
                        return(ip);
                    }
                    catch (Exception ex)
                    {
                        log.Error("Unable to build IPv6 address from next free: " + ex);
                    }
                }
            }
            return(null);
        }
Esempio n. 17
0
        /* (non-Javadoc)
         * @see java.lang.Runnable#run()
         */
        //public void Run()
        //{
        //    SetupPolicies(configObj, lifetime);
        //    try
        //    {
        //        if (doForwardUpdate)
        //        {
        //            ForwardDdnsUpdate fwdUpdate = new ForwardDdnsUpdate(fqdn, addr, duid);
        //            fwdUpdate.SetServer(fwdServer);
        //            fwdUpdate.SetZone(fwdZone);
        //            fwdUpdate.SetTtl(fwdTtl);
        //            fwdUpdate.SetTsigKeyName(fwdTsigKeyName);
        //            fwdUpdate.SetTsigAlgorithm(fwdTsigAlgorithm);
        //            fwdUpdate.SetTsigKeyData(fwdTsigKeyData);
        //            if (!isDelete)
        //                callback.FwdAddComplete(fwdUpdate.SendAdd());
        //            else
        //                callback.FwdDeleteComplete(fwdUpdate.SendDelete());
        //        }
        //        ReverseDdnsUpdate revUpdate = new ReverseDdnsUpdate(fqdn, addr, duid);
        //        revUpdate.SetServer(revServer);
        //        revUpdate.SetZone(revZone);
        //        revUpdate.SetRevZoneBitLength(revZoneBitLength);
        //        revUpdate.SetTtl(revTtl);
        //        revUpdate.SetTsigKeyName(revTsigKeyName);
        //        revUpdate.SetTsigAlgorithm(revTsigAlgorithm);
        //        revUpdate.SetTsigKeyData(revTsigKeyData);
        //        if (!isDelete)
        //            callback.RevAddComplete(revUpdate.SendAdd());
        //        else
        //            callback.RevDeleteComplete(revUpdate.SendDelete());
        //    }
        //    catch (Exception ex)
        //    {
        //        log.Error(ex, "Failure performing DDNS updates");
        //        callback.FwdAddComplete(false);
        //        callback.FwdDeleteComplete(false);
        //        callback.RevAddComplete(false);
        //        callback.RevDeleteComplete(false);
        //    }
        //}

        /**
         * Sets the up policies.
         *
         * @param addrBindingPool the new up policies
         */
        private void SetupPolicies(DhcpConfigObject addrBindingPool, long lifetime)
        {
            sync = DhcpServerPolicies.EffectivePolicyAsbool(requestMsg,
                                                            addrBindingPool, clientLink, Property.DDNS_SYNCHRONIZE);

            string zone = DhcpServerPolicies.EffectivePolicy(requestMsg,
                                                             addrBindingPool, clientLink, Property.DDNS_FORWARD_ZONE_NAME);

            if ((zone != null) && !string.IsNullOrEmpty(zone))
            {
                fwdZone = zone;
            }

            zone = DhcpServerPolicies.EffectivePolicy(requestMsg,
                                                      addrBindingPool, clientLink, Property.DDNS_REVERSE_ZONE_NAME);
            if ((zone != null) && !string.IsNullOrEmpty(zone))
            {
                revZone = zone;
            }

            revZoneBitLength = DhcpServerPolicies.EffectivePolicyAsInt(requestMsg,
                                                                       addrBindingPool, clientLink, Property.DDNS_REVERSE_ZONE_BITLENGTH);

            long  ttl      = 0;
            float ttlFloat = DhcpServerPolicies.EffectivePolicyAsFloat(requestMsg,
                                                                       addrBindingPool, clientLink, Property.DDNS_TTL);

            if (ttlFloat < 1)
            {
                // if less than one, then percentage of lifetime seconds
                ttl = (long)(lifetime * ttlFloat);
            }
            else
            {
                // if greater than one, then absolute number of seconds
                ttl = (long)ttlFloat;
            }

            fwdTtl   = ttl;
            ttlFloat = DhcpServerPolicies.EffectivePolicyAsFloat(requestMsg,
                                                                 addrBindingPool, clientLink, Property.DDNS_FORWARD_ZONE_TTL);
            if (ttlFloat < 1)
            {
                // if less than one, then percentage of lifetime seconds
                fwdTtl = (long)(lifetime * ttlFloat);
            }
            else
            {
                // if greater than one, then absolute number of seconds
                fwdTtl = (long)ttlFloat;
            }

            revTtl   = ttl;
            ttlFloat = DhcpServerPolicies.EffectivePolicyAsFloat(requestMsg,
                                                                 addrBindingPool, clientLink, Property.DDNS_REVERSE_ZONE_TTL);
            if (ttlFloat < 1)
            {
                // if less than one, then percentage of lifetime seconds
                revTtl = (long)(lifetime * ttlFloat);
            }
            else
            {
                // if greater than one, then absolute number of seconds
                revTtl = (long)ttlFloat;
            }

            string server = DhcpServerPolicies.EffectivePolicy(requestMsg,
                                                               addrBindingPool, clientLink, Property.DDNS_SERVER);

            fwdServer = server;
            revServer = server;

            server = DhcpServerPolicies.EffectivePolicy(requestMsg,
                                                        addrBindingPool, clientLink, Property.DDNS_FORWARD_ZONE_SERVER);
            if ((server != null) && !string.IsNullOrEmpty(server))
            {
                fwdServer = server;
            }
            server = DhcpServerPolicies.EffectivePolicy(requestMsg,
                                                        addrBindingPool, clientLink, Property.DDNS_REVERSE_ZONE_SERVER);
            if ((server != null) && !string.IsNullOrEmpty(server))
            {
                revServer = server;
            }

            string tsigKeyName = DhcpServerPolicies.EffectivePolicy(requestMsg,
                                                                    addrBindingPool, clientLink, Property.DDNS_TSIG_KEYNAME);

            fwdTsigKeyName = tsigKeyName;
            revTsigKeyName = tsigKeyName;

            tsigKeyName = DhcpServerPolicies.EffectivePolicy(requestMsg,
                                                             addrBindingPool, clientLink, Property.DDNS_FORWARD_ZONE_TSIG_KEYNAME);
            if ((tsigKeyName != null) && !string.IsNullOrEmpty(tsigKeyName))
            {
                fwdTsigKeyName = tsigKeyName;
            }
            tsigKeyName = DhcpServerPolicies.EffectivePolicy(requestMsg,
                                                             addrBindingPool, clientLink, Property.DDNS_REVERSE_ZONE_TSIG_KEYNAME);
            if ((tsigKeyName != null) && !string.IsNullOrEmpty(tsigKeyName))
            {
                revTsigKeyName = tsigKeyName;
            }

            string tsigAlgorithm = DhcpServerPolicies.EffectivePolicy(requestMsg,
                                                                      addrBindingPool, clientLink, Property.DDNS_TSIG_ALGORITHM);

            fwdTsigAlgorithm = tsigAlgorithm;
            revTsigAlgorithm = tsigAlgorithm;

            tsigAlgorithm = DhcpServerPolicies.EffectivePolicy(requestMsg,
                                                               addrBindingPool, clientLink, Property.DDNS_FORWARD_ZONE_TSIG_ALGORITHM);
            if ((tsigAlgorithm != null) && !string.IsNullOrEmpty(tsigAlgorithm))
            {
                fwdTsigAlgorithm = tsigAlgorithm;
            }
            tsigAlgorithm = DhcpServerPolicies.EffectivePolicy(requestMsg,
                                                               addrBindingPool, clientLink, Property.DDNS_REVERSE_ZONE_TSIG_ALGORITHM);
            if ((tsigAlgorithm != null) && !string.IsNullOrEmpty(tsigAlgorithm))
            {
                revTsigAlgorithm = tsigAlgorithm;
            }

            string tsigKeyData = DhcpServerPolicies.EffectivePolicy(requestMsg,
                                                                    addrBindingPool, clientLink, Property.DDNS_TSIG_KEYDATA);

            fwdTsigKeyData = tsigKeyData;
            revTsigKeyData = tsigKeyData;

            tsigKeyData = DhcpServerPolicies.EffectivePolicy(requestMsg,
                                                             addrBindingPool, clientLink, Property.DDNS_FORWARD_ZONE_TSIG_KEYDATA);
            if ((tsigKeyData != null) && !string.IsNullOrEmpty(tsigKeyData))
            {
                fwdTsigKeyData = tsigKeyData;
            }
            tsigKeyData = DhcpServerPolicies.EffectivePolicy(requestMsg,
                                                             addrBindingPool, clientLink, Property.DDNS_REVERSE_ZONE_TSIG_KEYDATA);
            if ((tsigKeyData != null) && !string.IsNullOrEmpty(tsigKeyData))
            {
                revTsigKeyData = tsigKeyData;
            }
        }
        public override bool Process()
        {
            //            If the server cannot find a client entry for the IA and the server
            //            determines that the addresses in the IA are not appropriate for the
            //            link to which the client's interface is attached according to the
            //            server's explicit configuration information, the server MAY send a
            //            Reply message to the client containing the client's IA, with the
            //            lifetimes for the addresses in the IA set to zero.  This Reply
            //            constitutes an explicit notification to the client that the addresses
            //            in the IA are no longer valid.  In this situation, if the server does
            //            not send a Reply message it silently discards the Rebind message.
            //
            //            If the server finds that any of the addresses are no longer
            //            appropriate for the link to which the client is attached, the server
            //            returns the address to the client with lifetimes of 0.
            //
            //            If the server finds the addresses in the IA for the client then the
            //            server SHOULD send back the IA to the client with new lifetimes and
            //            T1/T2 times.
            bool sendReply = true;
            DhcpV6ClientIdOption    clientIdOption = requestMsg.GetDhcpClientIdOption();
            List <DhcpV6IaNaOption> iaNaOptions    = requestMsg.GetIaNaOptions();

            if (((iaNaOptions != null) &&
                 iaNaOptions.Count > 0))
            {
                V6NaAddrBindingManager bindingMgr = dhcpServerConfig.GetNaAddrBindingMgr();
                if ((bindingMgr != null))
                {
                    foreach (DhcpV6IaNaOption dhcpIaNaOption in iaNaOptions)
                    {
                        log.Info(("Processing IA_NA Rebind: " + dhcpIaNaOption.ToString()));
                        Binding binding = bindingMgr.FindCurrentBinding(clientLink, clientIdOption, dhcpIaNaOption, requestMsg);
                        if ((binding != null))
                        {
                            //  zero out the lifetimes of any invalid addresses
                            if (!AllIaAddrsOnLink(dhcpIaNaOption, clientLink))
                            {
                                replyMsg.AddIaNaOption(dhcpIaNaOption);
                            }
                            else
                            {
                                binding = bindingMgr.UpdateBinding(binding, clientLink, clientIdOption, dhcpIaNaOption, requestMsg, IdentityAssoc.COMMITTED, _clientV4IP);
                                if ((binding != null))
                                {
                                    AddBindingToReply(clientLink, binding);
                                    bindings.Add(binding);
                                }
                                else
                                {
                                    AddIaNaOptionStatusToReply(dhcpIaNaOption, DhcpConstants.V6STATUS_CODE_NOADDRSAVAIL);
                                }
                            }
                        }
                        else if (DhcpServerPolicies.EffectivePolicyAsBoolean(requestMsg, clientLink.GetLink(), Property.VERIFY_UNKNOWN_REBIND))
                        {
                            //  zero out the lifetimes of any invalid addresses
                            AllIaAddrsOnLink(dhcpIaNaOption, clientLink);
                            replyMsg.AddIaNaOption(dhcpIaNaOption);
                        }
                    }
                }
                else
                {
                    log.Error(("Unable to process IA_NA Rebind:" + " No NaAddrBindingManager available"));
                }
            }

            List <DhcpV6IaTaOption> iaTaOptions = requestMsg.GetIaTaOptions();

            if (((iaTaOptions != null) &&
                 iaTaOptions.Count > 0))
            {
                V6TaAddrBindingManager bindingMgr = dhcpServerConfig.GetTaAddrBindingMgr();
                if ((bindingMgr != null))
                {
                    foreach (DhcpV6IaTaOption dhcpIaTaOption in iaTaOptions)
                    {
                        log.Info(("Processing IA_TA Rebind: " + dhcpIaTaOption.ToString()));
                        Binding binding = bindingMgr.FindCurrentBinding(clientLink, clientIdOption, dhcpIaTaOption, requestMsg);
                        if ((binding != null))
                        {
                            //  zero out the lifetimes of any invalid addresses
                            if (!AllIaAddrsOnLink(dhcpIaTaOption, clientLink))
                            {
                                replyMsg.AddIaTaOption(dhcpIaTaOption);
                            }
                            else
                            {
                                binding = bindingMgr.UpdateBinding(binding, clientLink, clientIdOption, dhcpIaTaOption, requestMsg, IdentityAssoc.COMMITTED, _clientV4IP);
                                if ((binding != null))
                                {
                                    AddBindingToReply(clientLink, binding);
                                    bindings.Add(binding);
                                }
                                else
                                {
                                    AddIaTaOptionStatusToReply(dhcpIaTaOption, DhcpConstants.V6STATUS_CODE_NOADDRSAVAIL);
                                }
                            }
                        }
                        else if (DhcpServerPolicies.EffectivePolicyAsBoolean(requestMsg, clientLink.GetLink(), Property.VERIFY_UNKNOWN_REBIND))
                        {
                            //  zero out the lifetimes of any invalid addresses
                            AllIaAddrsOnLink(dhcpIaTaOption, clientLink);
                            replyMsg.AddIaTaOption(dhcpIaTaOption);
                        }
                    }
                }
                else
                {
                    log.Error(("Unable to process IA_TA Rebind:" + " No TaAddrBindingManager available"));
                }
            }

            List <DhcpV6IaPdOption> iaPdOptions = requestMsg.GetIaPdOptions();

            if (((iaPdOptions != null) &&
                 iaPdOptions.Count > 0))
            {
                V6PrefixBindingManager bindingMgr = dhcpServerConfig.GetPrefixBindingMgr();
                if ((bindingMgr != null))
                {
                    foreach (DhcpV6IaPdOption dhcpIaPdOption in iaPdOptions)
                    {
                        log.Info(("Processing IA_PD Rebind: " + dhcpIaPdOption.ToString()));
                        Binding binding = bindingMgr.FindCurrentBinding(clientLink, clientIdOption, dhcpIaPdOption, requestMsg);
                        if ((binding != null))
                        {
                            //  zero out the lifetimes of any invalid addresses
                            if (!AllIaPrefixesOnLink(dhcpIaPdOption, clientLink))
                            {
                                replyMsg.AddIaPdOption(dhcpIaPdOption);
                            }
                            else
                            {
                                binding = bindingMgr.UpdateBinding(binding, clientLink, clientIdOption, dhcpIaPdOption, requestMsg, IdentityAssoc.COMMITTED, _clientV4IP);
                                if ((binding != null))
                                {
                                    AddBindingToReply(clientLink, binding);
                                    bindings.Add(binding);
                                }
                                else
                                {
                                    AddIaPdOptionStatusToReply(dhcpIaPdOption, DhcpConstants.V6STATUS_CODE_NOPREFIXAVAIL);
                                }
                            }
                        }
                        else if (DhcpServerPolicies.EffectivePolicyAsBoolean(requestMsg, clientLink.GetLink(), Property.VERIFY_UNKNOWN_REBIND))
                        {
                            //  zero out the lifetimes of any invalid addresses
                            AllIaPrefixesOnLink(dhcpIaPdOption, clientLink);
                            replyMsg.AddIaPdOption(dhcpIaPdOption);
                        }
                    }
                }
                else
                {
                    log.Error(("Unable to process IA_PD Rebind:" + " No PrefixBindingManager available"));
                }
            }

            if ((bindings.Count == 0 &&
                 !DhcpServerPolicies.EffectivePolicyAsBoolean(requestMsg, clientLink.GetLink(), Property.VERIFY_UNKNOWN_REBIND)))
            {
                sendReply = false;
            }

            if (sendReply)
            {
                replyMsg.SetMessageType(DhcpConstants.V6MESSAGE_TYPE_REPLY);
                if (bindings.Count == 0)
                {
                    PopulateReplyMsgOptions(clientLink);
                    ProcessDdnsUpdates(true);
                }
            }

            return(sendReply);
        }
Esempio n. 19
0
        protected void ProcessDdnsUpdates(bool sendUpdates)
        {
            bool doForwardUpdate = true;

            DhcpV4ClientFqdnOption clientFqdnOption = (DhcpV4ClientFqdnOption)_requestMsg.GetDhcpOption(DhcpConstants.V4OPTION_CLIENT_FQDN);
            DhcpV4HostnameOption   hostnameOption   = (DhcpV4HostnameOption)_requestMsg.GetDhcpOption(DhcpConstants.V4OPTION_HOSTNAME);

            if (clientFqdnOption == null && hostnameOption == null)
            {
                //TODO allow name generation?
                log.Debug("No Client FQDN nor hostname option in request.  Skipping DDNS update processing.");
                return;
            }

            string fqdn   = "";
            string domain = DhcpServerPolicies.DffectivePolicy(_clientLink.GetLink(), Property.DDNS_DOMAIN);
            DhcpV4ClientFqdnOption replyFqdnOption = null;

            if (clientFqdnOption != null)
            {
                replyFqdnOption = new DhcpV4ClientFqdnOption();
                replyFqdnOption.SetDomainName(clientFqdnOption.GetDomainName());
                replyFqdnOption.SetUpdateABit(false);
                replyFqdnOption.SetOverrideBit(false);
                replyFqdnOption.SetNoUpdateBit(false);
                replyFqdnOption.SetEncodingBit(clientFqdnOption.GetEncodingBit());
                replyFqdnOption.SetRcode1((short)0xff);     // RFC 4702 says server should set to 255
                replyFqdnOption.SetRcode2((short)0xff);     // RFC 4702 says server should set to 255

                fqdn = clientFqdnOption.GetDomainName();
                if ((fqdn == null) || (fqdn.Length <= 0))
                {
                    log.Error("Client FQDN option domain name is null/empty.  No DDNS udpates performed.");
                    replyFqdnOption.SetNoUpdateBit(true);   // tell client that server did no updates
                    _replyMsg.PutDhcpOption(replyFqdnOption);
                    return;
                }

                string policy = DhcpServerPolicies.EffectivePolicy(_requestMsg, _clientLink.GetLink(), Property.DDNS_UPDATE);
                log.Info("Server configuration for ddns.update policy: " + policy);
                if ((policy == null) || policy.Contains("none"))
                {
                    log.Info("Server configuration for ddns.update policy is null or 'none'." + "  No DDNS updates performed.");
                    replyFqdnOption.SetNoUpdateBit(true);   // tell client that server did no updates
                    _replyMsg.PutDhcpOption(replyFqdnOption);
                    return;
                }

                if (clientFqdnOption.GetNoUpdateBit() && policy.Contains("honorNoUpdate"))
                {
                    log.Info("Client FQDN NoUpdate flag set.  Server configured to honor request." + "  No DDNS updates performed.");
                    replyFqdnOption.SetNoUpdateBit(true);   // tell client that server did no updates
                    _replyMsg.PutDhcpOption(replyFqdnOption);
                    //TODO: RFC 4704 Section 6.1
                    //		...the server SHOULD delete any RRs that it previously added
                    //		via DNS updates for the client.
                    return;
                }

                if (!clientFqdnOption.GetUpdateABit() && policy.Contains("honorNoA"))
                {
                    log.Info("Client FQDN NoA flag set.  Server configured to honor request." + "  No FORWARD DDNS updates performed.");
                    doForwardUpdate = false;
                }
                else
                {
                    replyFqdnOption.SetUpdateABit(true);    // server will do update
                    if (!clientFqdnOption.GetUpdateABit())
                    {
                        replyFqdnOption.SetOverrideBit(true);   // tell client that we overrode request flag
                    }
                }

                if (!String.IsNullOrEmpty(domain))
                {
                    log.Info("Server configuration for domain policy: " + domain);
                    // if there is a configured domain, then replace the domain provide by the client
                    int dot = fqdn.IndexOf('.');
                    if (dot > 0)
                    {
                        fqdn = fqdn.Substring(0, dot + 1) + domain;
                    }
                    else
                    {
                        fqdn = fqdn + "." + domain;
                    }
                    replyFqdnOption.SetDomainName(fqdn);
                }
                // since the client DID send option 81, return it in the reply
                _replyMsg.PutDhcpOption(replyFqdnOption);
            }
            else
            {
                // The client did not send an FQDN option, so we'll try to formulate the FQDN
                // from the hostname option combined with the DDNS_DOMAIN policy setting.
                // A replyFqdnOption is fabricated to be stored with the binding for use
                // with the release/expire binding processing to remove the DDNS entry.
                replyFqdnOption = new DhcpV4ClientFqdnOption();
                fqdn            = hostnameOption.GetString();
                if (!String.IsNullOrEmpty(domain))
                {
                    log.Info("Server configuration for domain policy: " + domain);
                    fqdn = fqdn + "." + domain;
                    // since the client did NOT send option 81, do not put
                    // the fabricated fqdnOption into the reply packet
                    // but set the option so that is can be used below
                    // when storing the fqdnOption to the database, so
                    // that it can be used if/when the lease expires
                    replyFqdnOption.SetDomainName(fqdn);
                    // server will do the A record update, so set the flag
                    // for the option stored in the database, so server will
                    // remove the A record when the lease expires
                    replyFqdnOption.SetUpdateABit(true);
                }
                else
                {
                    log.Error("No DDNS domain configured.  No DDNS udpates performed.");
                    replyFqdnOption.SetNoUpdateBit(true);   // tell client that server did no updates
                    _replyMsg.PutDhcpOption(replyFqdnOption);
                    return;
                }
            }

            if (sendUpdates)
            {
                foreach (Binding binding in _bindings)
                {
                    if (binding.GetState() == Binding.COMMITTED)
                    {
                        HashSet <BindingObject> bindingObjs = binding.GetBindingObjects();
                        if (bindingObjs != null)
                        {
                            foreach (var bindingObj in bindingObjs)
                            {
                                V4BindingAddress bindingAddr  = (V4BindingAddress)bindingObj;
                                DhcpConfigObject configObj    = bindingAddr.GetConfigObj();
                                DdnsCallback     ddnsComplete = new DhcpV4DdnsComplete(bindingAddr, replyFqdnOption);
                                DdnsUpdater      ddns         = new DdnsUpdater(_requestMsg, _clientLink.GetLink(), configObj, bindingAddr.GetIpAddress(), fqdn, _requestMsg.GetChAddr(), configObj.GetValidLifetime(), doForwardUpdate, false, ddnsComplete);
                                ddns.ProcessUpdates();
                            }
                        }
                    }
                }
            }
        }
Esempio n. 20
0
        protected void ProcessDdnsUpdates(bool sendUpdates)
        {
            DhcpV6ClientFqdnOption clientFqdnOption = ((DhcpV6ClientFqdnOption)(this.requestMsg.GetDhcpOption(DhcpConstants.V6OPTION_CLIENT_FQDN)));

            if ((clientFqdnOption == null))
            {
                // TODO allow name generation?
                log.Debug("No Client FQDN option in request.  Skipping DDNS update processing.");
                return;
            }

            bool includeFqdnOptionInReply = false;

            if (((this.requestMsg.GetRequestedOptionCodes() != null) &&
                 this.requestMsg.GetRequestedOptionCodes().Contains(DhcpConstants.V6OPTION_CLIENT_FQDN)))
            {
                //  RFC 4704 section 6 says:
                //    Servers MUST only include a Client FQDN option in ADVERTISE and REPLY
                //    messages if the client included a Client FQDN option and the Client
                //    FQDN option is requested by the Option Request option in the client's
                //    message to which the server is responding.
                includeFqdnOptionInReply = true;
            }

            DhcpV6ClientFqdnOption replyFqdnOption = new DhcpV6ClientFqdnOption();

            replyFqdnOption.SetDomainName(clientFqdnOption.GetDomainName());
            replyFqdnOption.SetUpdateAaaaBit(false);
            replyFqdnOption.SetOverrideBit(false);
            replyFqdnOption.SetNoUpdateBit(false);
            string fqdn = clientFqdnOption.GetDomainName();

            if (((fqdn == null) ||
                 (fqdn.Length <= 0)))
            {
                log.Error("Client FQDN option domain name is null/empty.  No DDNS udpates performed.");
                if (includeFqdnOptionInReply)
                {
                    replyFqdnOption.SetNoUpdateBit(true);
                    //  tell client that server did no updates
                    this.replyMsg.PutDhcpOption(replyFqdnOption);
                }

                return;
            }

            String policy = DhcpServerPolicies.EffectivePolicy(this.requestMsg, this.clientLink.GetLink(), Property.DDNS_UPDATE);

            log.Info(("Server configuration for ddns.update policy: " + policy));
            if (((policy == null) ||
                 policy.ToLower() == "none"))
            {
                log.Info(("Server configuration for ddns.update policy is null or \'none\'." + "  No DDNS updates performed."));
                if (includeFqdnOptionInReply)
                {
                    replyFqdnOption.SetNoUpdateBit(true);
                    //  tell client that server did no updates
                    this.replyMsg.PutDhcpOption(replyFqdnOption);
                }

                return;
            }

            if ((clientFqdnOption.GetNoUpdateBit() && policy.ToLower() == "honorNoUpdate".ToLower()))
            {
                log.Info(("Client FQDN NoUpdate flag set.  Server configured to honor request." + "  No DDNS updates performed."));
                if (includeFqdnOptionInReply)
                {
                    replyFqdnOption.SetNoUpdateBit(true);
                    //  tell client that server did no updates
                    this.replyMsg.PutDhcpOption(replyFqdnOption);
                }

                // TODO: RFC 4704 Section 6.1
                //         ...the server SHOULD delete any RRs that it previously added
                //         via DNS updates for the client.
                return;
            }

            bool doForwardUpdate = true;

            if ((!clientFqdnOption.GetUpdateAaaaBit() &&
                 policy.ToLower() == "honorNoAAAA".ToLower()))
            {
                log.Info(("Client FQDN NoAAAA flag set.  Server configured to honor request." + "  No FORWARD DDNS updates performed."));
                doForwardUpdate = false;
            }
            else
            {
                replyFqdnOption.SetUpdateAaaaBit(true);
                //  server will do update
                if (!clientFqdnOption.GetUpdateAaaaBit())
                {
                    replyFqdnOption.SetOverrideBit(true);
                }

                //  tell client that we overrode request flag
            }

            string domain = DhcpServerPolicies.EffectivePolicy(this.clientLink.GetLink(), Property.DDNS_DOMAIN);

            if (((domain != null) &&
                 domain.Count() > 0))
            {
                log.Info(("Server configuration for domain policy: " + domain));
                //  if there is a configured domain, then replace the domain provide by the client
                int dot = fqdn.IndexOf('.');
                if ((dot > 0))
                {
                    fqdn = (fqdn.Substring(0, (dot + 1)) + domain);
                }
                else
                {
                    fqdn = (fqdn + ("." + domain));
                }

                replyFqdnOption.SetDomainName(fqdn);
            }

            if (includeFqdnOptionInReply)
            {
                this.replyMsg.PutDhcpOption(replyFqdnOption);
            }

            if (sendUpdates)
            {
                foreach (Binding binding in this.bindings)
                {
                    if ((binding.GetState() == Binding.COMMITTED))
                    {
                        HashSet <BindingObject> bindingObjs = binding.GetBindingObjects();
                        if ((bindingObjs != null))
                        {
                            foreach (BindingObject bindingObj in bindingObjs)
                            {
                                V6BindingAddress bindingAddr  = ((V6BindingAddress)(bindingObj));
                                DhcpConfigObject configObj    = bindingAddr.GetConfigObj();
                                DdnsCallback     ddnsComplete = new DhcpV6DdnsComplete(bindingAddr, replyFqdnOption);
                                DdnsUpdater      ddns         = new DdnsUpdater(this.requestMsg, this.clientLink.GetLink(), configObj, bindingAddr.GetIpAddress(), fqdn, this.requestMsg.GetDhcpClientIdOption().GetDuid(), configObj.GetValidLifetime(), doForwardUpdate, false, ddnsComplete);
                                ddns.ProcessUpdates();
                            }
                        }
                    }
                }
            }
        }