Esempio n. 1
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");
     }
 }
        /// <summary>
        ///  Find the current binding, if any, for the given client identity association (IA).
        /// </summary>
        /// <param name="clientLink">link for the client request message</param>
        /// <param name="duid">DUID of the client</param>
        /// <param name="iatype">the IAID of the client request</param>
        /// <param name="iaid"> IAID of the client request</param>
        /// <param name="requestMsg">requestMsg the client request message</param>
        /// <returns>return the existing Binding for this client request</returns>
        protected Binding FindCurrentBinding(DhcpLink clientLink, byte[] duid, byte iatype, long iaid, DhcpMessage requestMsg)
        {
            Binding binding = null;

            lock (_lock)
            {
                try
                {
                    IdentityAssoc ia = iaMgr.FindIA(duid, iatype, iaid);
                    if (ia != null)
                    {
                        _log.Info("Found current binding for " + IdentityAssoc.KeyToString(duid, iatype, iaid) + " state=" + ia.GetState());
                        binding = BuildBindingFromIa(ia, clientLink, requestMsg);
                        if (binding != null)
                        {
                            _log.Info("Successfully built Binding object: " + binding);
                        }
                        else
                        {
                            _log.Error("Failed to build Binding object");
                        }
                    }
                    else
                    {
                        _log.Info("No current binding found for " + IdentityAssoc.KeyToString(duid, iatype, iaid));
                    }
                }
                catch (Exception ex)
                {
                    _log.Error("Failed to find current binding");
                }
            }
            return(binding);
        }
Esempio n. 3
0
        /// <summary>
        /// Callback from the ReaperTimerTask started when the BindingManager initialized.
        /// Find any expired addresses as of now, and expire them already.
        /// </summary>
        public void ExpireAddresses()
        {
            List <IdentityAssoc> expiredIAs = iaMgr.FindExpiredIAs(GetIaType());

            if ((expiredIAs != null) && expiredIAs.Count > 0)
            {
                log.Info("Found " + expiredIAs.Count + " expired bindings of type: " +
                         IdentityAssoc.IaTypeToString(GetIaType()));
                foreach (IdentityAssoc ia in expiredIAs)
                {
                    List <IaAddress> expiredAddrs = ia.GetIaAddresses();
                    if ((expiredAddrs != null) && expiredAddrs.Count > 0)
                    {
                        // due to the implementation of findExpiredIAs, each IdentityAssoc
                        // SHOULD have only one IaAddress within it to be expired
                        log.Info("Found " + expiredAddrs.Count + " expired bindings for IA: " +
                                 "duid=" + Util.ToHexString(ia.GetDuid()) + " iaid=" + ia.GetIaid());
                        foreach (IaAddress iaAddress in expiredAddrs)
                        {
                            ExpireIaAddress(ia, iaAddress);
                        }
                    }
                }
            }
        }
        /// <summary>
        ///  Builds a new Binding.Create a new IdentityAssoc from the given
        ///  tuple and wrap that IdentityAssoc in a Binding.
        /// </summary>
        /// <param name="clientLink">client link</param>
        /// <param name="duid">DUID</param>
        /// <param name="iatype">IA type</param>
        /// <param name="iaid">IAID</param>
        /// <param name="state"></param>
        /// <returns> binding (a wrapped IdentityAssoc)</returns>
        private Binding BuildBinding(DhcpLink clientLink, byte[] duid, byte iatype, long iaid,
                                     byte state)
        {
            IdentityAssoc ia = new IdentityAssoc();

            ia.SetDuid(duid);
            ia.SetIatype(iatype);
            ia.SetIaid(iaid);
            ia.SetState(state);
            return(new Binding(ia, clientLink));
        }
Esempio n. 5
0
        public Binding(IdentityAssoc ia, DhcpLink dhcpLink)
        {
            this.origIa = ia;
            //  save a reference to the original IA
            this.SetDhcpOptions(ia.GetDhcpOptions());
            this.SetDuid(ia.GetDuid());
            this.SetIaAddresses(ia.GetIaAddresses());
            this.SetIaid(ia.GetIaid());
            this.SetIatype(ia.GetIatype());
            this.SetId(ia.GetId());
            this.SetState(ia.GetState());

            this.dhcpLink = dhcpLink;
        }
        /// <summary>
        /// Checks if the duid-iatype-iaid tuple matches the given IA.
        /// </summary>
        /// <param name="duid">DUID</param>
        /// <param name="iatype">IA type</param>
        /// <param name="iaid">IAID</param>
        /// <param name="ia">IA</param>
        /// <returns>true, if is my ia</returns>
        protected bool IsMyIa(byte[] duid, byte iatype, long iaid, IdentityAssoc ia)
        {
            bool rc = false;

            if (duid != null)
            {
                if (Array.Equals(ia.GetDuid(), duid) &&
                    (ia.GetIatype() == iatype) &&
                    (ia.GetIaid() == iaid))
                {
                    rc = true;
                }
            }
            return(rc);
        }
        /**
         * Create a Binding given an IdentityAssoc loaded from the database.
         *
         * @param ia the ia
         * @param clientLink the client link
         * @param requestMsg the request msg
         *
         * @return the binding
         */
        protected override Binding BuildBindingFromIa(IdentityAssoc ia, DhcpLink clientLink,
                                                      DhcpMessage requestMsg)
        {
            Binding          binding = new Binding(ia, clientLink);
            List <IaAddress> iaAddrs = ia.GetIaAddresses();

            if ((iaAddrs != null) && iaAddrs.Count > 0)
            {
                List <IaAddress> bindingAddrs = new List <IaAddress>();
                foreach (IaAddress iaAddr in iaAddrs)
                {
                    if (!clientLink.GetSubnet().Contains(iaAddr.GetIpAddress()))
                    {
                        log.Info("Ignoring off-link binding address: " +
                                 iaAddr.GetIpAddress().ToString());
                        continue;
                    }
                    V4BindingAddress bindingAddr   = null;
                    StaticBinding    staticBinding =
                        FindStaticBinding(clientLink.GetLink(), ia.GetDuid(),
                                          ia.GetIatype(), ia.GetIaid(), requestMsg);
                    if (staticBinding != null)
                    {
                        bindingAddr =
                            BuildV4StaticBindingFromIaAddr(iaAddr, staticBinding);
                    }
                    else
                    {
                        bindingAddr =
                            BuildV4BindingAddressFromIaAddr(iaAddr, clientLink.GetLink(), requestMsg);
                    }
                    if (bindingAddr != null)
                    {
                        bindingAddrs.Add(bindingAddr);
                    }
                }
                // replace the collection of IaAddresses with BindingAddresses
                binding.SetIaAddresses(bindingAddrs);
            }
            else
            {
                log.Warn("IA has no addresses, binding is empty.");
            }
            return(binding);
        }
Esempio n. 8
0
 /// <summary>
 /// Decline an IaAddress.  This is done when the client declines an address.
 /// Perform a DDNS delete just in case it was already registered, then mark
 /// the address as declined (unavailable).
 /// </summary>
 /// <param name="ia">iaAddr the declined IaAddress.</param>
 /// <param name="iaAddr">iaAddr the declined IaAddress.</param>
 public void DeclineIaAddress(IdentityAssoc ia, IaAddress iaAddr)
 {
     try
     {
         log.Info("Declining address: " + iaAddr.GetIpAddress().ToString());
         //DdnsDelete(ia, iaAddr);
         iaAddr.SetStartTime(DateTime.Now);
         iaAddr.SetPreferredEndTime(DateTime.Now);
         iaAddr.SetValidEndTime(DateTime.Now);
         iaAddr.SetState(IaAddress.DECLINED);
         iaMgr.UpdateIaAddr(iaAddr);
         log.Info("Address declined: " + iaAddr.ToString());
     }
     catch (Exception ex)
     {
         log.Error("Failed to decline address");
     }
 }
        /**
         * Create a Binding given an IdentityAssoc loaded from the database.
         *
         * @param ia the ia
         * @param clientLink the client link
         * @param requestMsg the request msg
         *
         * @return the binding
         */
        protected override Binding BuildBindingFromIa(IdentityAssoc ia,
                                                      DhcpLink clientLink, DhcpMessage requestMsg)
        {
            Binding          binding = new Binding(ia, clientLink);
            List <IaAddress> iaPrefs = ia.GetIaAddresses();

            if ((iaPrefs != null) && iaPrefs.Count > 0)
            {
                List <IaAddress> bindingPrefixes = new List <IaAddress>();
                foreach (IaAddress iaAddr in iaPrefs)
                {
                    // off-link check needed only for v4?
                    //				if (!clientLink.getSubnet().contains(iaAddr.getIpAddress())) {
                    //					log.info("Ignoring off-link binding address: " +
                    //							iaAddr.getIpAddress().getHostAddress());
                    //					continue;
                    //				}
                    V6BindingPrefix bindingPrefix = null;
                    StaticBinding   staticBinding = FindStaticBinding(clientLink.GetLink(), ia.GetDuid(), ia.GetIatype(), ia.GetIaid(), requestMsg);
                    if (staticBinding != null)
                    {
                        bindingPrefix =
                            BuildV6BindingPrefixFromIaPrefix((IaPrefix)iaAddr, staticBinding);
                    }
                    else
                    {
                        bindingPrefix =
                            BuildBindingAddrFromIaPrefix((IaPrefix)iaAddr, clientLink.GetLink(), requestMsg);
                    }
                    if (bindingPrefix != null)
                    {
                        bindingPrefixes.Add(bindingPrefix);
                    }
                }
                // replace the collection of IaPrefixes with BindingPrefixes
                binding.SetIaAddresses(bindingPrefixes);
            }
            else
            {
                log.Warn("IA has no prefixes, binding is empty.");
            }
            return(binding);
        }
Esempio n. 10
0
        /**
         * Perform the DDNS delete processing when a lease is released or expired.
         *
         * @param ia the IdentityAssoc of the client
         * @param iaAddr the released or expired IaAddress
         */
        protected override void DdnsDelete(IdentityAssoc ia, IaAddress iaAddr)
        {
            DhcpV6ClientFqdnOption clientFqdnOption = null;

            try
            {
                if ((ia != null) && (iaAddr != null))
                {
                    List <DhcpOption> opts = iaAddr.GetDhcpOptions();
                    if (opts != null)
                    {
                        foreach (DhcpOption opt in opts)
                        {
                            if (opt.GetCode() == DhcpConstants.V6OPTION_CLIENT_FQDN)
                            {
                                clientFqdnOption = new DhcpV6ClientFqdnOption();
                                //clientFqdnOption.Decode(ByteBuffer.Wrap(opt.GetValue()));
                                break;
                            }
                        }
                    }
                    if (clientFqdnOption != null)
                    {
                        string fqdn = clientFqdnOption.GetDomainName();
                        if (!String.IsNullOrEmpty(fqdn))
                        {
                            DhcpLink link = serverConfig.FindLinkForAddress(iaAddr.GetIpAddress());
                            if (link != null)
                            {
                                V6BindingAddress bindingAddr   = null;
                                StaticBinding    staticBinding =
                                    FindStaticBinding(link.GetLink(), ia.GetDuid(),
                                                      ia.GetIatype(), ia.GetIaid(), null);
                                if (staticBinding != null)
                                {
                                    bindingAddr =
                                        BuildV6StaticBindingFromIaAddr(iaAddr, staticBinding);
                                }
                                else
                                {
                                    bindingAddr =
                                        BuildV6BindingAddressFromIaAddr(iaAddr, link, null);    // safe to send null requestMsg
                                }
                                if (bindingAddr != null)
                                {
                                    DdnsCallback ddnsComplete =
                                        new DhcpV6DdnsComplete(bindingAddr, clientFqdnOption);

                                    DhcpConfigObject configObj = bindingAddr.GetConfigObj();

                                    DdnsUpdater ddns =
                                        new DdnsUpdater(link.GetLink(), configObj,
                                                        bindingAddr.GetIpAddress(), fqdn, ia.GetDuid(),
                                                        configObj.GetValidLifetime(),
                                                        clientFqdnOption.GetUpdateAaaaBit(), true,
                                                        ddnsComplete);

                                    ddns.ProcessUpdates();
                                }
                                else
                                {
                                    log.Error("Failed to find binding for address: " +
                                              iaAddr.GetIpAddress().ToString());
                                }
                            }
                            else
                            {
                                log.Error("Failed to find link for binding address: " +
                                          iaAddr.GetIpAddress().ToString());
                            }
                        }
                        else
                        {
                            log.Error("FQDN is null or empty.  No DDNS deletes performed.");
                        }
                    }
                    else
                    {
                        log.Warn("No Client FQDN option in current binding.  No DDNS deletes performed.");
                    }
                }
            }
            catch (Exception ex)
            {
                log.Error("Failed to perform DDNS delete");
            }
        }
 /// <summary>
 ///  Create a Binding given an IdentityAssoc loaded from the database.
 /// </summary>
 /// <param name="ia">IA</param>
 /// <param name="clientLink">client link</param>
 /// <param name="requestMsg">request message</param>
 /// <returns>binding</returns>
 protected abstract Binding BuildBindingFromIa(IdentityAssoc ia,
                                               DhcpLink clientLink, DhcpMessage requestMsg);
        /// <summary>
        /// Get list of IP addresses for the given client IA request.
        /// </summary>
        /// <param name="clientLink">link for the client request message</param>
        /// <param name="duid">DUID of the client</param>
        /// <param name="iatype">IA type of the client request</param>
        /// <param name="iaid">IAID of the client request</param>
        /// <param name="requestAddrs">list of requested IP addresses, if any</param>
        /// <param name="requestMsg">client request message</param>
        /// <returns>list of IPAddress</returns>
        protected List <IPAddress> GetInetAddrs(DhcpLink clientLink, byte[] duid, byte iatype, long iaid, List <IPAddress> requestAddrs, DhcpMessage requestMsg, IPAddress clientV4IPAddress)
        {
            List <IPAddress> inetAddrs = new List <IPAddress>();

            if ((requestAddrs != null) && requestAddrs.Count > 0)
            {
                foreach (IPAddress reqAddr in requestAddrs)
                {
                    IPAddress addr = reqAddr;
                    if (!addr.Equals(DhcpConstants.ZEROADDR_V6))
                    {
                        BindingPool bp = FindBindingPool(clientLink.GetLink(), addr, requestMsg);
                        if (bp.IsFree(new BigInteger(addr.GetAddressBytes())) == false)
                        {
                            continue;
                        }
                        if (bp == null)
                        {
                            _log.Warn("No BindingPool found for requested client address: " + addr.ToString());
                            if (iatype == IdentityAssoc.PD_TYPE)
                            {
                                // TAHI tests want NoPrefixAvail in this case
                                _log.Warn("Requested prefix is not available, returning");
                                return(inetAddrs);
                            }
                            // if there is no pool for the requested address, then skip it
                            // because that address is either off-link or no longer valid
                            continue;
                        }
                        _log.Info("Searching existing bindings for requested IP=" + addr.ToString());
                        IdentityAssoc ia = null;
                        try
                        {
                            ia = iaMgr.FindIA(addr);
                            if (ia != null)
                            {
                                // the address is assigned to an IA, which we
                                // don't expect to be this IA, because we would
                                // have found it using findCurrentBinding...
                                // but, perhaps another thread just created it?
                                if (IsMyIa(duid, iatype, iaid, ia))
                                {
                                    _log.Warn("Requested IP=" + addr.ToString() + " is already held by THIS client " + IdentityAssoc.KeyToString(duid, iatype, iaid) + ".  Allowing this requested IP.");
                                }
                                else
                                {
                                    _log.Info("Requested IP=" + addr.ToString() + " is held by ANOTHER client " + IdentityAssoc.KeyToString(duid, iatype, iaid));
                                    // the address is held by another IA, so get a new one
                                    addr = GetNextFreeAddress(clientLink, requestMsg, clientV4IPAddress);
                                }
                            }
                            if (addr != null)
                            {
                                inetAddrs.Add(addr);
                            }
                        }
                        catch
                        {
                            _log.Error("Failure finding IA for address");
                        }
                    }
                }
            }

            if (inetAddrs == null || inetAddrs.Count == 0)
            {
                // the client did not request any valid addresses, so get the next one
                IPAddress inetAddr = GetNextFreeAddress(clientLink, requestMsg, clientV4IPAddress);
                if (inetAddr != null)
                {
                    inetAddrs.Add(inetAddr);
                }
            }
            return(inetAddrs);
        }
Esempio n. 13
0
 /// <summary>
 /// Perform the DDNS delete processing when a lease is released or expired.
 /// </summary>
 /// <param name="ia">iaAddr the released or expired IaAddress </param>
 /// <param name="iaAddr">iaAddr the released or expired IaAddress </param>
 protected abstract void DdnsDelete(IdentityAssoc ia, IaAddress iaAddr);